<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: flow::util Namespace Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Public API.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceflow.html">flow</a></li><li class="navelem"><a class="el" href="namespaceflow_1_1util.html">util</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#namespaces">Namespaces</a> &#124;
<a href="#nested-classes">Classes</a> &#124;
<a href="#typedef-members">Typedefs</a> &#124;
<a href="#func-members">Functions</a>  </div>
  <div class="headertitle"><div class="title">flow::util Namespace Reference</div></div>
</div><!--header-->
<div class="contents">

<p>Flow module containing miscellaneous general-use facilities that don't fit into any other Flow module.  
<a href="namespaceflow_1_1util.html#details">More...</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="namespaces" name="namespaces"></a>
Namespaces</h2></td></tr>
<tr class="memitem:namespaceflow_1_1util_1_1this__thread"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util_1_1this__thread.html">this_thread</a></td></tr>
<tr class="memdesc:namespaceflow_1_1util_1_1this__thread"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for standard this-thread namespace. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">A hand-optimized and API-tweaked replacement for <code>vector&lt;uint8_t&gt;</code>, i.e., buffer of bytes inside an allocated area of equal or larger size; also optionally supports limited garbage-collected memory pool functionality and SHM-friendly custom-allocator support.  <a href="classflow_1_1util_1_1Basic__blob.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Basic__string__view.html">Basic_string_view</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Essentially alias for a C++17-conforming string-view class template, which is a very lightweight <code>std::string</code>-like representation of a character sequence already in memory.  <a href="classflow_1_1util_1_1Basic__string__view.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html">Blob_with_log_context</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight"><a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> that works in regular heap (and is itself placed in heap or stack) and memorizes a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">log::Logger</a>, enabling easier logging albeit with a small perf trade-off.  <a href="classflow_1_1util_1_1Blob__with__log__context.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Container__traits.html">Container_traits</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Properties of various container types.  <a href="classflow_1_1util_1_1Container__traits.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Container__traits_3_01boost_1_1unordered__set_3_01T_01_4_01_4.html">Container_traits&lt; boost::unordered_set&lt; T &gt; &gt;</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Traits of <code>boost::unordered_set</code>.  <a href="classflow_1_1util_1_1Container__traits_3_01boost_1_1unordered__set_3_01T_01_4_01_4.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Container__traits_3_01std_1_1map_3_01K_00_01V_01_4_01_4.html">Container_traits&lt; std::map&lt; K, V &gt; &gt;</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Traits of <code>std::map</code>.  <a href="classflow_1_1util_1_1Container__traits_3_01std_1_1map_3_01K_00_01V_01_4_01_4.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Container__traits_3_01std_1_1set_3_01T_01_4_01_4.html">Container_traits&lt; std::set&lt; T &gt; &gt;</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Traits of <code>std::set</code>.  <a href="classflow_1_1util_1_1Container__traits_3_01std_1_1set_3_01T_01_4_01_4.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Container__traits_3_01util_1_1Linked__hash__map_3_01K_00_01V_01_4_01_4.html">Container_traits&lt; util::Linked_hash_map&lt; K, V &gt; &gt;</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Traits of <a class="el" href="classflow_1_1util_1_1Linked__hash__map.html" title="An object of this class is a map that combines the lookup speed of a boost::unordered_map&lt;&gt; and order...">flow::util::Linked_hash_map</a>.  <a href="classflow_1_1util_1_1Container__traits_3_01util_1_1Linked__hash__map_3_01K_00_01V_01_4_01_4.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Container__traits_3_01util_1_1Linked__hash__set_3_01T_00_01Hash_00_01Pred_01_4_01_4.html">Container_traits&lt; util::Linked_hash_set&lt; T, Hash, Pred &gt; &gt;</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Traits of <a class="el" href="classflow_1_1util_1_1Linked__hash__set.html" title="An object of this class is a set that combines the lookup speed of an unordered_set&lt;&gt; and ordering an...">flow::util::Linked_hash_set</a>.  <a href="classflow_1_1util_1_1Container__traits_3_01util_1_1Linked__hash__set_3_01T_00_01Hash_00_01Pred_01_4_01_4.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Linked__hash__map.html">Linked_hash_map</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">An object of this class is a map that combines the lookup speed of a <code>boost::unordered_map&lt;&gt;</code> and ordering and iterator stability capabilities of an <code>std::list&lt;&gt;</code>.  <a href="classflow_1_1util_1_1Linked__hash__map.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Linked__hash__set.html">Linked_hash_set</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">An object of this class is a set that combines the lookup speed of an <code>unordered_set&lt;&gt;</code> and ordering and iterator stability capabilities of an <code>std::list&lt;&gt;</code>.  <a href="classflow_1_1util_1_1Linked__hash__set.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structflow_1_1util_1_1Noncopyable.html">Noncopyable</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Useful as a no-unique-address private member to make a type noncopyable while keeping that type an aggregate (can be direct-initialized).  <a href="structflow_1_1util_1_1Noncopyable.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Null__interface.html">Null_interface</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">An empty interface, consisting of nothing but a default <code>virtual</code> destructor, intended as a boiler-plate-reducing base for any other (presumably <code>virtual</code>-method-having) class that would otherwise require a default <code>virtual</code> destructor.  <a href="classflow_1_1util_1_1Null__interface.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range.html">Rnd_gen_uniform_range</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Simple, non-thread-safe uniform-range random number generator.  <a href="classflow_1_1util_1_1Rnd__gen__uniform__range.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range__base.html">Rnd_gen_uniform_range_base</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Base class for <a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range.html" title="Simple, non-thread-safe uniform-range random number generator.">Rnd_gen_uniform_range</a> and <a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range__mt.html" title="Identical to Rnd_gen_uniform_range but safe for concurrent RNG given a single object.">Rnd_gen_uniform_range_mt</a> for various aliases and similar, so template arguments need not be involved.  <a href="classflow_1_1util_1_1Rnd__gen__uniform__range__base.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range__mt.html">Rnd_gen_uniform_range_mt</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Identical to <a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range.html" title="Simple, non-thread-safe uniform-range random number generator.">Rnd_gen_uniform_range</a> but safe for concurrent RNG given a single object.  <a href="classflow_1_1util_1_1Rnd__gen__uniform__range__mt.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Scoped__setter.html">Scoped_setter</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">A simple RAII-pattern class template that, at construction, sets the specified location in memory to a specified value, memorizing the previous contents; and at destruction restores the value.  <a href="classflow_1_1util_1_1Scoped__setter.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html">Shared_ptr_alias_holder</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Convenience class template that endows the given subclass <code>T</code> with nested aliases <code>Ptr</code> and <code>Const_ptr</code> aliased to <code>shared_ptr&lt;T&gt;</code> and <code>shared_ptr&lt;const T&gt;</code> respectively.  <a href="classflow_1_1util_1_1Shared__ptr__alias__holder.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1String__ostream.html">String_ostream</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Similar to <code>ostringstream</code> but allows fast read-only access directly into the <code>std::string</code> being written; and some limited write access to that string.  <a href="classflow_1_1util_1_1String__ostream.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Unique__id__holder.html">Unique_id_holder</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Each object of this class stores (at construction) and returns (on demand) a numeric ID unique from all other objects of the same class ever constructed, across all time from program start to end.  <a href="classflow_1_1util_1_1Unique__id__holder.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="typedef-members" name="typedef-members"></a>
Typedefs</h2></td></tr>
<tr class="memitem:a2c085aa47872fe7e4dbba0703e23923c"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a2c085aa47872fe7e4dbba0703e23923c">Blob_sans_log_context</a> = <a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt;&gt;</td></tr>
<tr class="memdesc:a2c085aa47872fe7e4dbba0703e23923c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for a <a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> that allocates/deallocates in regular heap and is itself assumed to be stored in heap or on stack; sharing feature compile-time-disabled (with perf boost as a result).  <a href="namespaceflow_1_1util.html#a2c085aa47872fe7e4dbba0703e23923c">More...</a><br /></td></tr>
<tr class="separator:a2c085aa47872fe7e4dbba0703e23923c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0edd9dd6bf51e7457477123b419f5bf6"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a0edd9dd6bf51e7457477123b419f5bf6">Sharing_blob_sans_log_context</a> = <a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt; std::allocator&lt; <a class="el" href="namespaceflow.html#ae02da22c4a101eaab447511c905e4f32">uint8_t</a> &gt;, true &gt;</td></tr>
<tr class="memdesc:a0edd9dd6bf51e7457477123b419f5bf6"><td class="mdescLeft">&#160;</td><td class="mdescRight">Identical to <a class="el" href="namespaceflow_1_1util.html#a2c085aa47872fe7e4dbba0703e23923c" title="Short-hand for a Basic_blob that allocates/deallocates in regular heap and is itself assumed to be st...">Blob_sans_log_context</a> but with sharing feature compile-time-enabled.  <a href="namespaceflow_1_1util.html#a0edd9dd6bf51e7457477123b419f5bf6">More...</a><br /></td></tr>
<tr class="separator:a0edd9dd6bf51e7457477123b419f5bf6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af09888b3a8feaff209b6625e493bc338"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">Blob</a> = <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html">Blob_with_log_context</a>&lt;&gt;</td></tr>
<tr class="memdesc:af09888b3a8feaff209b6625e493bc338"><td class="mdescLeft">&#160;</td><td class="mdescRight">A concrete <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html" title="Basic_blob that works in regular heap (and is itself placed in heap or stack) and memorizes a log::Lo...">Blob_with_log_context</a> that compile-time-disables <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a0044410b7d1f541978a309f02b2739d3" title="Applicable to !zero() blobs, this returns an identical Basic_blob that shares (co-owns) *this allocat...">Basic_blob::share()</a> and the sharing API derived from it.  <a href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">More...</a><br /></td></tr>
<tr class="separator:af09888b3a8feaff209b6625e493bc338"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a164f043f9edc5e5ec8fc99a0e4eb9064"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a164f043f9edc5e5ec8fc99a0e4eb9064">Sharing_blob</a> = <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html">Blob_with_log_context</a>&lt; true &gt;</td></tr>
<tr class="memdesc:a164f043f9edc5e5ec8fc99a0e4eb9064"><td class="mdescLeft">&#160;</td><td class="mdescRight">A concrete <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html" title="Basic_blob that works in regular heap (and is itself placed in heap or stack) and memorizes a log::Lo...">Blob_with_log_context</a> that compile-time-enables <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a0044410b7d1f541978a309f02b2739d3" title="Applicable to !zero() blobs, this returns an identical Basic_blob that shares (co-owns) *this allocat...">Basic_blob::share()</a> and the sharing API derived from it.  <a href="namespaceflow_1_1util.html#a164f043f9edc5e5ec8fc99a0e4eb9064">More...</a><br /></td></tr>
<tr class="separator:a164f043f9edc5e5ec8fc99a0e4eb9064"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa0d10f5a906b3229f48979aa43e9ff7e"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">Scheduled_task_handle</a> = boost::shared_ptr&lt; Scheduled_task_handle_state &gt;</td></tr>
<tr class="memdesc:aa0d10f5a906b3229f48979aa43e9ff7e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Black-box type that represents a handle to a scheduled task as scheduled by <a class="el" href="namespaceflow_1_1util.html#aad8c8f7335eb892350dc386cb4be397e" title="Identical to schedule_task_from_now() except the time is specified in absolute terms.">schedule_task_at()</a> or <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar, which can be (optionally) used to control the scheduled task after it has been thus scheduled.  <a href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">More...</a><br /></td></tr>
<tr class="separator:aa0d10f5a906b3229f48979aa43e9ff7e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:add471ec4a0f0b76793c9c84adb4916d5"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#add471ec4a0f0b76793c9c84adb4916d5">Scheduled_task_const_handle</a> = boost::shared_ptr&lt; const Scheduled_task_handle_state &gt;</td></tr>
<tr class="memdesc:add471ec4a0f0b76793c9c84adb4916d5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Equivalent to <code>Scheduled_task_handle</code> but refers to immutable version of a task.  <a href="namespaceflow_1_1util.html#add471ec4a0f0b76793c9c84adb4916d5">More...</a><br /></td></tr>
<tr class="separator:add471ec4a0f0b76793c9c84adb4916d5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aafa03984c5012ef7db2e7d01b6909a83"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#aafa03984c5012ef7db2e7d01b6909a83">Scheduled_task</a> = Function&lt; void(bool short_fire)&gt;</td></tr>
<tr class="memdesc:aafa03984c5012ef7db2e7d01b6909a83"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for tasks that can be scheduled/fired by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> and similar.  <a href="namespaceflow_1_1util.html#aafa03984c5012ef7db2e7d01b6909a83">More...</a><br /></td></tr>
<tr class="separator:aafa03984c5012ef7db2e7d01b6909a83"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae4dc52186797094b3040379ff19124c9"><td class="memItemLeft" align="right" valign="top"><a id="ae4dc52186797094b3040379ff19124c9" name="ae4dc52186797094b3040379ff19124c9"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>String_view</b> = <a class="el" href="classflow_1_1util_1_1Basic__string__view.html">Basic_string_view</a>&lt; char &gt;</td></tr>
<tr class="memdesc:ae4dc52186797094b3040379ff19124c9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Commonly used <code>char</code>-based <a class="el" href="classflow_1_1util_1_1Basic__string__view.html" title="Essentially alias for a C++17-conforming string-view class template, which is a very lightweight std:...">Basic_string_view</a>. See its doc header. <br /></td></tr>
<tr class="separator:ae4dc52186797094b3040379ff19124c9"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af030c3119f060a9630afca31098a78a5"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">Thread</a> = boost::thread</td></tr>
<tr class="memdesc:af030c3119f060a9630afca31098a78a5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for standard thread class.  <a href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">More...</a><br /></td></tr>
<tr class="separator:af030c3119f060a9630afca31098a78a5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0a4e7b2d3107bd630e0dc0c0b8f2e4de"><td class="memItemLeft" align="right" valign="top"><a id="a0a4e7b2d3107bd630e0dc0c0b8f2e4de" name="a0a4e7b2d3107bd630e0dc0c0b8f2e4de"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Thread_id</b> = Thread::id</td></tr>
<tr class="memdesc:a0a4e7b2d3107bd630e0dc0c0b8f2e4de"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for an OS-provided ID of a <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5" title="Short-hand for standard thread class.">util::Thread</a>. <br /></td></tr>
<tr class="separator:a0a4e7b2d3107bd630e0dc0c0b8f2e4de"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac3e89a8a271b0ddc76ac2a0ce488dea4"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">Task_engine</a> = boost::asio::io_context</td></tr>
<tr class="memdesc:ac3e89a8a271b0ddc76ac2a0ce488dea4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for boost.asio event service, the central class of boost.asio.  <a href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">More...</a><br /></td></tr>
<tr class="separator:ac3e89a8a271b0ddc76ac2a0ce488dea4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa59354ab408e978c8a7bda1a4706924e"><td class="memItemLeft" align="right" valign="top"><a id="aa59354ab408e978c8a7bda1a4706924e" name="aa59354ab408e978c8a7bda1a4706924e"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Strand</b> = Task_engine::strand</td></tr>
<tr class="memdesc:aa59354ab408e978c8a7bda1a4706924e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for boost.asio strand, an ancillary class that works with <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">Task_engine</a> for advanced task scheduling. <br /></td></tr>
<tr class="separator:aa59354ab408e978c8a7bda1a4706924e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae7416d64d2989051104bb396e28e15e6"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6">Timer</a> = boost::asio::basic_waitable_timer&lt; <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00">Fine_clock</a> &gt;</td></tr>
<tr class="memdesc:ae7416d64d2989051104bb396e28e15e6"><td class="mdescLeft">&#160;</td><td class="mdescRight">boost.asio timer.  <a href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6">More...</a><br /></td></tr>
<tr class="separator:ae7416d64d2989051104bb396e28e15e6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab22fd89e165a9e6deaa174bc0dfdc8de"><td class="memItemLeft" align="right" valign="top"><a id="ab22fd89e165a9e6deaa174bc0dfdc8de" name="ab22fd89e165a9e6deaa174bc0dfdc8de"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Auto_cleanup</b> = boost::shared_ptr&lt; void &gt;</td></tr>
<tr class="memdesc:ab22fd89e165a9e6deaa174bc0dfdc8de"><td class="mdescLeft">&#160;</td><td class="mdescRight">Helper type for <a class="el" href="namespaceflow_1_1util.html#a09a032f8e1e77a3afc0b7df115a773e1" title="Provides a way to execute arbitrary (cleanup) code at the exit of the current block.">setup_auto_cleanup()</a>. <br /></td></tr>
<tr class="separator:ab22fd89e165a9e6deaa174bc0dfdc8de"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af1b28edb7bad743c1c77f6b982cc3196"><td class="memItemLeft" align="right" valign="top"><a id="af1b28edb7bad743c1c77f6b982cc3196" name="af1b28edb7bad743c1c77f6b982cc3196"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Udp_endpoint</b> = boost::asio::ip::udp::endpoint</td></tr>
<tr class="memdesc:af1b28edb7bad743c1c77f6b982cc3196"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for the UDP endpoint (IP/port) type. <br /></td></tr>
<tr class="separator:af1b28edb7bad743c1c77f6b982cc3196"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a331b3b73d9d633101d6f0ebc1c829701"><td class="memItemLeft" align="right" valign="top"><a id="a331b3b73d9d633101d6f0ebc1c829701" name="a331b3b73d9d633101d6f0ebc1c829701"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Ip_address_v4</b> = boost::asio::ip::address_v4</td></tr>
<tr class="memdesc:a331b3b73d9d633101d6f0ebc1c829701"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for the IPv4 address type. <br /></td></tr>
<tr class="separator:a331b3b73d9d633101d6f0ebc1c829701"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a2ed0f6ab85f5df463bb10913b0764540"><td class="memItemLeft" align="right" valign="top"><a id="a2ed0f6ab85f5df463bb10913b0764540" name="a2ed0f6ab85f5df463bb10913b0764540"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Ip_address_v6</b> = boost::asio::ip::address_v6</td></tr>
<tr class="memdesc:a2ed0f6ab85f5df463bb10913b0764540"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for the IPv6 address type. <br /></td></tr>
<tr class="separator:a2ed0f6ab85f5df463bb10913b0764540"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:add6ade273326f27eaf9bfd170a909626"><td class="memItemLeft" align="right" valign="top"><a id="add6ade273326f27eaf9bfd170a909626" name="add6ade273326f27eaf9bfd170a909626"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Mutex_non_recursive</b> = boost::mutex</td></tr>
<tr class="memdesc:add6ade273326f27eaf9bfd170a909626"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for non-reentrant, exclusive mutex. ("Reentrant" = one can lock an already-locked-in-that-thread mutex.) <br /></td></tr>
<tr class="separator:add6ade273326f27eaf9bfd170a909626"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9c7a5df07c2e86c788de9e6bbaee77d5"><td class="memItemLeft" align="right" valign="top"><a id="a9c7a5df07c2e86c788de9e6bbaee77d5" name="a9c7a5df07c2e86c788de9e6bbaee77d5"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Mutex_recursive</b> = boost::recursive_mutex</td></tr>
<tr class="memdesc:a9c7a5df07c2e86c788de9e6bbaee77d5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for reentrant, exclusive mutex. <br /></td></tr>
<tr class="separator:a9c7a5df07c2e86c788de9e6bbaee77d5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a62b5ba6d6a549ac20e2c055e72bef421"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421">Mutex_shared_non_recursive</a> = boost::shared_mutex</td></tr>
<tr class="memdesc:a62b5ba6d6a549ac20e2c055e72bef421"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for non-reentrant, shared-or-exclusive mutex.  <a href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421">More...</a><br /></td></tr>
<tr class="separator:a62b5ba6d6a549ac20e2c055e72bef421"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aeee121f0277371517fd2f5c3a20d8112"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112">Mutex_noop_shared_non_recursive</a> = boost::null_mutex</td></tr>
<tr class="memdesc:aeee121f0277371517fd2f5c3a20d8112"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for a mutex type equivalent to <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">util::Mutex_shared_non_recursive</a> &ndash; except that the lock/unlock mutex ops all do nothing.  <a href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112">More...</a><br /></td></tr>
<tr class="separator:aeee121f0277371517fd2f5c3a20d8112"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5d2247b715da63e4b960909561b90ae7"><td class="memTemplParams" colspan="2">template&lt;typename Mutex &gt; </td></tr>
<tr class="memitem:a5d2247b715da63e4b960909561b90ae7"><td class="memTemplItemLeft" align="right" valign="top">using&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a5d2247b715da63e4b960909561b90ae7">Lock_guard</a> = boost::unique_lock&lt; Mutex &gt;</td></tr>
<tr class="memdesc:a5d2247b715da63e4b960909561b90ae7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for advanced-capability RAII lock guard for any mutex, ensuring exclusive ownership of that mutex.  <a href="namespaceflow_1_1util.html#a5d2247b715da63e4b960909561b90ae7">More...</a><br /></td></tr>
<tr class="separator:a5d2247b715da63e4b960909561b90ae7"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac4f0492f15f46f70581feac50b9217ee"><td class="memTemplParams" colspan="2">template&lt;typename Shared_mutex &gt; </td></tr>
<tr class="memitem:ac4f0492f15f46f70581feac50b9217ee"><td class="memTemplItemLeft" align="right" valign="top">using&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#ac4f0492f15f46f70581feac50b9217ee">Shared_lock_guard</a> = boost::shared_lock&lt; Shared_mutex &gt;</td></tr>
<tr class="memdesc:ac4f0492f15f46f70581feac50b9217ee"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for <em>shared mode</em> advanced-capability RAII lock guard, particuarly for <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">Mutex_shared_non_recursive</a> mutexes.  <a href="namespaceflow_1_1util.html#ac4f0492f15f46f70581feac50b9217ee">More...</a><br /></td></tr>
<tr class="separator:ac4f0492f15f46f70581feac50b9217ee"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9495b3e37e9d27bcc7767a4b6ce87ff4"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a9495b3e37e9d27bcc7767a4b6ce87ff4">Lock_guard_non_recursive</a> = boost::unique_lock&lt; <a class="el" href="namespaceflow_1_1util.html#add6ade273326f27eaf9bfd170a909626">Mutex_non_recursive</a> &gt;</td></tr>
<tr class="memdesc:a9495b3e37e9d27bcc7767a4b6ce87ff4"><td class="mdescLeft">&#160;</td><td class="mdescRight">(Deprecated given C++1x) Short-hand for advanced-capability RAII lock guard for <a class="el" href="namespaceflow_1_1util.html#add6ade273326f27eaf9bfd170a909626" title="Short-hand for non-reentrant, exclusive mutex. (&quot;Reentrant&quot; = one can lock an already-locked-in-that-...">Mutex_non_recursive</a> mutexes.  <a href="namespaceflow_1_1util.html#a9495b3e37e9d27bcc7767a4b6ce87ff4">More...</a><br /></td></tr>
<tr class="separator:a9495b3e37e9d27bcc7767a4b6ce87ff4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a015b84cfa3076b8e75d16ec44a5514a3"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a015b84cfa3076b8e75d16ec44a5514a3">Lock_guard_recursive</a> = boost::unique_lock&lt; <a class="el" href="namespaceflow_1_1util.html#a9c7a5df07c2e86c788de9e6bbaee77d5">Mutex_recursive</a> &gt;</td></tr>
<tr class="memdesc:a015b84cfa3076b8e75d16ec44a5514a3"><td class="mdescLeft">&#160;</td><td class="mdescRight">(Deprecated given C++1x) Short-hand for advanced-capability RAII lock guard for <a class="el" href="namespaceflow_1_1util.html#a9c7a5df07c2e86c788de9e6bbaee77d5" title="Short-hand for reentrant, exclusive mutex.">Mutex_recursive</a> mutexes.  <a href="namespaceflow_1_1util.html#a015b84cfa3076b8e75d16ec44a5514a3">More...</a><br /></td></tr>
<tr class="separator:a015b84cfa3076b8e75d16ec44a5514a3"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a689388b6eb7e760933d99381d65cacca"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a689388b6eb7e760933d99381d65cacca">Lock_guard_shared_non_recursive_sh</a> = boost::shared_lock&lt; <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421">Mutex_shared_non_recursive</a> &gt;</td></tr>
<tr class="memdesc:a689388b6eb7e760933d99381d65cacca"><td class="mdescLeft">&#160;</td><td class="mdescRight">(Deprecated given C++1x) Short-hand for <em>shared mode</em> advanced-capability RAII lock guard for <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">Mutex_shared_non_recursive</a> mutexes.  <a href="namespaceflow_1_1util.html#a689388b6eb7e760933d99381d65cacca">More...</a><br /></td></tr>
<tr class="separator:a689388b6eb7e760933d99381d65cacca"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9df3cc2f3aec0c0353443b9d6c81e638"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a9df3cc2f3aec0c0353443b9d6c81e638">Lock_guard_shared_non_recursive_ex</a> = boost::unique_lock&lt; <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421">Mutex_shared_non_recursive</a> &gt;</td></tr>
<tr class="memdesc:a9df3cc2f3aec0c0353443b9d6c81e638"><td class="mdescLeft">&#160;</td><td class="mdescRight">(Deprecated given C++1x) Short-hand for <em>exclusive mode</em> advanced-capability RAII lock guard for <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">Mutex_shared_non_recursive</a> mutexes.  <a href="namespaceflow_1_1util.html#a9df3cc2f3aec0c0353443b9d6c81e638">More...</a><br /></td></tr>
<tr class="separator:a9df3cc2f3aec0c0353443b9d6c81e638"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9e5fae573be960434c4c9dacd48c9c11"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a9e5fae573be960434c4c9dacd48c9c11">Lock_guard_noop_shared_non_recursive_sh</a> = boost::shared_lock&lt; <a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112">Mutex_noop_shared_non_recursive</a> &gt;</td></tr>
<tr class="memdesc:a9e5fae573be960434c4c9dacd48c9c11"><td class="mdescLeft">&#160;</td><td class="mdescRight">(Deprecated given C++1x) Equivalent to <a class="el" href="namespaceflow_1_1util.html#a689388b6eb7e760933d99381d65cacca" title="(Deprecated given C++1x) Short-hand for shared mode advanced-capability RAII lock guard for Mutex_sha...">Lock_guard_shared_non_recursive_sh</a> but applied to <a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112" title="Short-hand for a mutex type equivalent to util::Mutex_shared_non_recursive – except that the lock/unl...">Mutex_noop_shared_non_recursive</a>.  <a href="namespaceflow_1_1util.html#a9e5fae573be960434c4c9dacd48c9c11">More...</a><br /></td></tr>
<tr class="separator:a9e5fae573be960434c4c9dacd48c9c11"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:add56211dee74c212c19028f1ded2a785"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#add56211dee74c212c19028f1ded2a785">Lock_guard_noop_shared_non_recursive_ex</a> = boost::unique_lock&lt; <a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112">Mutex_noop_shared_non_recursive</a> &gt;</td></tr>
<tr class="memdesc:add56211dee74c212c19028f1ded2a785"><td class="mdescLeft">&#160;</td><td class="mdescRight">(Deprecated given C++1x) Equivalent to <a class="el" href="namespaceflow_1_1util.html#a9df3cc2f3aec0c0353443b9d6c81e638" title="(Deprecated given C++1x) Short-hand for exclusive mode advanced-capability RAII lock guard for Mutex_...">Lock_guard_shared_non_recursive_ex</a> but applied to <a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112" title="Short-hand for a mutex type equivalent to util::Mutex_shared_non_recursive – except that the lock/unl...">Mutex_noop_shared_non_recursive</a>.  <a href="namespaceflow_1_1util.html#add56211dee74c212c19028f1ded2a785">More...</a><br /></td></tr>
<tr class="separator:add56211dee74c212c19028f1ded2a785"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="func-members" name="func-members"></a>
Functions</h2></td></tr>
<tr class="memitem:a71eaa4ab6a2673ed34fa8989c47a7bc0"><td class="memTemplParams" colspan="2">template&lt;typename Allocator , bool S_SHARING_ALLOWED&gt; </td></tr>
<tr class="memitem:a71eaa4ab6a2673ed34fa8989c47a7bc0"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a71eaa4ab6a2673ed34fa8989c47a7bc0">swap</a> (<a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt; Allocator, S_SHARING_ALLOWED &gt; &amp;blob1, <a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt; Allocator, S_SHARING_ALLOWED &gt; &amp;blob2, <a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr=0)</td></tr>
<tr class="memdesc:a71eaa4ab6a2673ed34fa8989c47a7bc0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Equivalent to <code>blob1.swap(blob2)</code>.  <a href="namespaceflow_1_1util.html#a71eaa4ab6a2673ed34fa8989c47a7bc0">More...</a><br /></td></tr>
<tr class="separator:a71eaa4ab6a2673ed34fa8989c47a7bc0"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af567381736851969f6e8812c54404028"><td class="memTemplParams" colspan="2">template&lt;typename Allocator , bool S_SHARING_ALLOWED&gt; </td></tr>
<tr class="memitem:af567381736851969f6e8812c54404028"><td class="memTemplItemLeft" align="right" valign="top">bool&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#af567381736851969f6e8812c54404028">blobs_sharing</a> (const <a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt; Allocator, S_SHARING_ALLOWED &gt; &amp;blob1, const <a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt; Allocator, S_SHARING_ALLOWED &gt; &amp;blob2)</td></tr>
<tr class="memdesc:af567381736851969f6e8812c54404028"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns <code>true</code> if and only if both given objects are not <code>zero() == true</code>, and they either co-own a common underlying buffer, or <em>are</em> the same object.  <a href="namespaceflow_1_1util.html#af567381736851969f6e8812c54404028">More...</a><br /></td></tr>
<tr class="separator:af567381736851969f6e8812c54404028"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae3835e26994f760a6324280d3a646b91"><td class="memTemplParams" colspan="2">template&lt;bool S_SHARING_ALLOWED&gt; </td></tr>
<tr class="memitem:ae3835e26994f760a6324280d3a646b91"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#ae3835e26994f760a6324280d3a646b91">swap</a> (<a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html">Blob_with_log_context</a>&lt; S_SHARING_ALLOWED &gt; &amp;blob1, <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html">Blob_with_log_context</a>&lt; S_SHARING_ALLOWED &gt; &amp;blob2)</td></tr>
<tr class="memdesc:ae3835e26994f760a6324280d3a646b91"><td class="mdescLeft">&#160;</td><td class="mdescRight">On top of the similar <a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> related function, logs using the stored log context of <code>blob1</code>.  <a href="namespaceflow_1_1util.html#ae3835e26994f760a6324280d3a646b91">More...</a><br /></td></tr>
<tr class="separator:ae3835e26994f760a6324280d3a646b91"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9bec37057b3abab90a9732d293116e5b"><td class="memTemplParams" colspan="2">template&lt;typename Key , typename Mapped , typename Hash , typename Pred &gt; </td></tr>
<tr class="memitem:a9bec37057b3abab90a9732d293116e5b"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a9bec37057b3abab90a9732d293116e5b">swap</a> (<a class="el" href="classflow_1_1util_1_1Linked__hash__map.html">Linked_hash_map</a>&lt; Key, Mapped, Hash, Pred &gt; &amp;val1, <a class="el" href="classflow_1_1util_1_1Linked__hash__map.html">Linked_hash_map</a>&lt; Key, Mapped, Hash, Pred &gt; &amp;val2)</td></tr>
<tr class="memdesc:a9bec37057b3abab90a9732d293116e5b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Equivalent to <code>val1.swap(val2)</code>.  <a href="namespaceflow_1_1util.html#a9bec37057b3abab90a9732d293116e5b">More...</a><br /></td></tr>
<tr class="separator:a9bec37057b3abab90a9732d293116e5b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac7fd808e839d422a3f74fbea57fe367e"><td class="memTemplParams" colspan="2">template&lt;typename Key , typename Hash , typename Pred &gt; </td></tr>
<tr class="memitem:ac7fd808e839d422a3f74fbea57fe367e"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#ac7fd808e839d422a3f74fbea57fe367e">swap</a> (<a class="el" href="classflow_1_1util_1_1Linked__hash__set.html">Linked_hash_set</a>&lt; Key, Hash, Pred &gt; &amp;val1, <a class="el" href="classflow_1_1util_1_1Linked__hash__set.html">Linked_hash_set</a>&lt; Key, Hash, Pred &gt; &amp;val2)</td></tr>
<tr class="memdesc:ac7fd808e839d422a3f74fbea57fe367e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Equivalent to <code>val1.swap(val2)</code>.  <a href="namespaceflow_1_1util.html#ac7fd808e839d422a3f74fbea57fe367e">More...</a><br /></td></tr>
<tr class="separator:ac7fd808e839d422a3f74fbea57fe367e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad92e68a1b22556f2625292098c0036a2"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#ad92e68a1b22556f2625292098c0036a2">scheduled_task_cancel</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, <a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">Scheduled_task_handle</a> task)</td></tr>
<tr class="memdesc:ad92e68a1b22556f2625292098c0036a2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Attempts to prevent the execution of a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task.  <a href="namespaceflow_1_1util.html#ad92e68a1b22556f2625292098c0036a2">More...</a><br /></td></tr>
<tr class="separator:ad92e68a1b22556f2625292098c0036a2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:abe8d04de7ba9ac770112ee585b77cd20"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#abe8d04de7ba9ac770112ee585b77cd20">scheduled_task_short_fire</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, <a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">Scheduled_task_handle</a> task)</td></tr>
<tr class="memdesc:abe8d04de7ba9ac770112ee585b77cd20"><td class="mdescLeft">&#160;</td><td class="mdescRight">Attempts to reschedule a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task to fire immediately.  <a href="namespaceflow_1_1util.html#abe8d04de7ba9ac770112ee585b77cd20">More...</a><br /></td></tr>
<tr class="separator:abe8d04de7ba9ac770112ee585b77cd20"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9a0812b36dc401a3b2ac5e60e2a070d0"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79">Fine_duration</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a9a0812b36dc401a3b2ac5e60e2a070d0">scheduled_task_fires_from_now_or_canceled</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, <a class="el" href="namespaceflow_1_1util.html#add471ec4a0f0b76793c9c84adb4916d5">Scheduled_task_const_handle</a> task)</td></tr>
<tr class="memdesc:a9a0812b36dc401a3b2ac5e60e2a070d0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns how long remains until a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task fires; or negative time if that point is in the past; or special value if the task has been canceled.  <a href="namespaceflow_1_1util.html#a9a0812b36dc401a3b2ac5e60e2a070d0">More...</a><br /></td></tr>
<tr class="separator:a9a0812b36dc401a3b2ac5e60e2a070d0"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a79a0f182b38898771d669475d3e963a4"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a79a0f182b38898771d669475d3e963a4">scheduled_task_fired</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, <a class="el" href="namespaceflow_1_1util.html#add471ec4a0f0b76793c9c84adb4916d5">Scheduled_task_const_handle</a> task)</td></tr>
<tr class="memdesc:a79a0f182b38898771d669475d3e963a4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns whether a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task has already fired.  <a href="namespaceflow_1_1util.html#a79a0f182b38898771d669475d3e963a4">More...</a><br /></td></tr>
<tr class="separator:a79a0f182b38898771d669475d3e963a4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad339cf2543e0ad692203817b19e4e8ed"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#ad339cf2543e0ad692203817b19e4e8ed">scheduled_task_canceled</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, <a class="el" href="namespaceflow_1_1util.html#add471ec4a0f0b76793c9c84adb4916d5">Scheduled_task_const_handle</a> task)</td></tr>
<tr class="memdesc:ad339cf2543e0ad692203817b19e4e8ed"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns whether a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task has been canceled.  <a href="namespaceflow_1_1util.html#ad339cf2543e0ad692203817b19e4e8ed">More...</a><br /></td></tr>
<tr class="separator:ad339cf2543e0ad692203817b19e4e8ed"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a74d4a66fb00055be4e1bd6ee98e04667"><td class="memTemplParams" colspan="2">template&lt;typename Scheduled_task_handler &gt; </td></tr>
<tr class="memitem:a74d4a66fb00055be4e1bd6ee98e04667"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">Scheduled_task_handle</a>&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667">schedule_task_from_now</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, const <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79">Fine_duration</a> &amp;from_now, bool single_threaded, <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">Task_engine</a> *task_engine, Scheduled_task_handler &amp;&amp;task_body_moved)</td></tr>
<tr class="memdesc:a74d4a66fb00055be4e1bd6ee98e04667"><td class="mdescLeft">&#160;</td><td class="mdescRight">Schedule the given function to execute in a certain amount of time: A handy wrapper around <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> (asio's timer facility).  <a href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667">More...</a><br /></td></tr>
<tr class="separator:a74d4a66fb00055be4e1bd6ee98e04667"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aad8c8f7335eb892350dc386cb4be397e"><td class="memTemplParams" colspan="2">template&lt;typename Scheduled_task_handler &gt; </td></tr>
<tr class="memitem:aad8c8f7335eb892350dc386cb4be397e"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">Scheduled_task_handle</a>&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#aad8c8f7335eb892350dc386cb4be397e">schedule_task_at</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, const <a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8">Fine_time_pt</a> &amp;at, bool single_threaded, <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">Task_engine</a> *task_engine, Scheduled_task_handler &amp;&amp;task_body_moved)</td></tr>
<tr class="memdesc:aad8c8f7335eb892350dc386cb4be397e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Identical to <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> except the time is specified in absolute terms.  <a href="namespaceflow_1_1util.html#aad8c8f7335eb892350dc386cb4be397e">More...</a><br /></td></tr>
<tr class="separator:aad8c8f7335eb892350dc386cb4be397e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad92ad411feccf73908abe6ed130d48f5"><td class="memItemLeft" align="right" valign="top">boost::chrono::microseconds&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#ad92ad411feccf73908abe6ed130d48f5">time_since_posix_epoch</a> ()</td></tr>
<tr class="memdesc:ad92ad411feccf73908abe6ed130d48f5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Get the current POSIX (Unix) time as a duration from the Epoch time point.  <a href="namespaceflow_1_1util.html#ad92ad411feccf73908abe6ed130d48f5">More...</a><br /></td></tr>
<tr class="separator:ad92ad411feccf73908abe6ed130d48f5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0955a29930075ac1fe393896c089b911"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a0955a29930075ac1fe393896c089b911">beautify_chrono_ostream</a> (std::ostream *os)</td></tr>
<tr class="memdesc:a0955a29930075ac1fe393896c089b911"><td class="mdescLeft">&#160;</td><td class="mdescRight">Sets certain <code>chrono</code>-related formatting on the given <code>ostream</code> that results in a consistent, desirable output of <code>duration</code>s and certain types of <code>time_point</code>s.  <a href="namespaceflow_1_1util.html#a0955a29930075ac1fe393896c089b911">More...</a><br /></td></tr>
<tr class="separator:a0955a29930075ac1fe393896c089b911"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a418b56a178c07100eef78da5c9d6ee7a"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a418b56a178c07100eef78da5c9d6ee7a">deep_size</a> (const std::string &amp;val)</td></tr>
<tr class="memdesc:a418b56a178c07100eef78da5c9d6ee7a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Estimate of memory footprint of the given value, including memory allocated on its behalf &ndash; but excluding its shallow <code>sizeof</code>! &ndash; in bytes.  <a href="namespaceflow_1_1util.html#a418b56a178c07100eef78da5c9d6ee7a">More...</a><br /></td></tr>
<tr class="separator:a418b56a178c07100eef78da5c9d6ee7a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0f681afaf67a0f917cf43a7ae893a015"><td class="memTemplParams" colspan="2">template&lt;typename Time_unit , typename N_items &gt; </td></tr>
<tr class="memitem:a0f681afaf67a0f917cf43a7ae893a015"><td class="memTemplItemLeft" align="right" valign="top">double&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a0f681afaf67a0f917cf43a7ae893a015">to_mbit_per_sec</a> (N_items items_per_time, size_t bits_per_item=8)</td></tr>
<tr class="memdesc:a0f681afaf67a0f917cf43a7ae893a015"><td class="mdescLeft">&#160;</td><td class="mdescRight">Utility that converts a bandwidth in arbitrary units in both numerator and denominator to the same bandwidth in megabits per second.  <a href="namespaceflow_1_1util.html#a0f681afaf67a0f917cf43a7ae893a015">More...</a><br /></td></tr>
<tr class="separator:a0f681afaf67a0f917cf43a7ae893a015"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6b7316b3ed6d89f54c91e17c2aab101e"><td class="memTemplParams" colspan="2">template&lt;typename Integer &gt; </td></tr>
<tr class="memitem:a6b7316b3ed6d89f54c91e17c2aab101e"><td class="memTemplItemLeft" align="right" valign="top">Integer&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a6b7316b3ed6d89f54c91e17c2aab101e">ceil_div</a> (Integer dividend, Integer divisor)</td></tr>
<tr class="memdesc:a6b7316b3ed6d89f54c91e17c2aab101e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the result of the given non-negative integer divided by a positive integer, rounded up to the nearest integer.  <a href="namespaceflow_1_1util.html#a6b7316b3ed6d89f54c91e17c2aab101e">More...</a><br /></td></tr>
<tr class="separator:a6b7316b3ed6d89f54c91e17c2aab101e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab10bc9e8bef148f875aa743fe0852743"><td class="memTemplParams" colspan="2">template&lt;typename T &gt; </td></tr>
<tr class="memitem:ab10bc9e8bef148f875aa743fe0852743"><td class="memTemplItemLeft" align="right" valign="top">bool&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#ab10bc9e8bef148f875aa743fe0852743">in_closed_range</a> (T const &amp;min_val, T const &amp;val, T const &amp;max_val)</td></tr>
<tr class="memdesc:ab10bc9e8bef148f875aa743fe0852743"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns <code>true</code> if and only if the given value is within the given range, inclusive.  <a href="namespaceflow_1_1util.html#ab10bc9e8bef148f875aa743fe0852743">More...</a><br /></td></tr>
<tr class="separator:ab10bc9e8bef148f875aa743fe0852743"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8ae762ea4f743a98a73953d7f9ec2164"><td class="memTemplParams" colspan="2">template&lt;typename T &gt; </td></tr>
<tr class="memitem:a8ae762ea4f743a98a73953d7f9ec2164"><td class="memTemplItemLeft" align="right" valign="top">bool&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a8ae762ea4f743a98a73953d7f9ec2164">in_open_closed_range</a> (T const &amp;min_val, T const &amp;val, T const &amp;max_val)</td></tr>
<tr class="memdesc:a8ae762ea4f743a98a73953d7f9ec2164"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns <code>true</code> if and only if the given value is within the given range, given as a (low, high] pair.  <a href="namespaceflow_1_1util.html#a8ae762ea4f743a98a73953d7f9ec2164">More...</a><br /></td></tr>
<tr class="separator:a8ae762ea4f743a98a73953d7f9ec2164"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a024ddda9acb2b66f2a1b35cdb0c016aa"><td class="memTemplParams" colspan="2">template&lt;typename T &gt; </td></tr>
<tr class="memitem:a024ddda9acb2b66f2a1b35cdb0c016aa"><td class="memTemplItemLeft" align="right" valign="top">bool&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a024ddda9acb2b66f2a1b35cdb0c016aa">in_closed_open_range</a> (T const &amp;min_val, T const &amp;val, T const &amp;max_val)</td></tr>
<tr class="memdesc:a024ddda9acb2b66f2a1b35cdb0c016aa"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns <code>true</code> if and only if the given value is within the given range, given as a [low, high) pair.  <a href="namespaceflow_1_1util.html#a024ddda9acb2b66f2a1b35cdb0c016aa">More...</a><br /></td></tr>
<tr class="separator:a024ddda9acb2b66f2a1b35cdb0c016aa"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a733448fee07c2a77e343a3f1590ff82e"><td class="memTemplParams" colspan="2">template&lt;typename T &gt; </td></tr>
<tr class="memitem:a733448fee07c2a77e343a3f1590ff82e"><td class="memTemplItemLeft" align="right" valign="top">bool&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a733448fee07c2a77e343a3f1590ff82e">in_open_open_range</a> (T const &amp;min_val, T const &amp;val, T const &amp;max_val)</td></tr>
<tr class="memdesc:a733448fee07c2a77e343a3f1590ff82e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns <code>true</code> if and only if the given value is within the given range, given as a (low, high) pair.  <a href="namespaceflow_1_1util.html#a733448fee07c2a77e343a3f1590ff82e">More...</a><br /></td></tr>
<tr class="separator:a733448fee07c2a77e343a3f1590ff82e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a03984e29450abf9cf287c501d6c8f866"><td class="memTemplParams" colspan="2">template&lt;typename Container &gt; </td></tr>
<tr class="memitem:a03984e29450abf9cf287c501d6c8f866"><td class="memTemplItemLeft" align="right" valign="top">bool&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a03984e29450abf9cf287c501d6c8f866">key_exists</a> (const Container &amp;container, const typename Container::key_type &amp;key)</td></tr>
<tr class="memdesc:a03984e29450abf9cf287c501d6c8f866"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns <code>true</code> if and only if the given key is present at least once in the given associative container.  <a href="namespaceflow_1_1util.html#a03984e29450abf9cf287c501d6c8f866">More...</a><br /></td></tr>
<tr class="separator:a03984e29450abf9cf287c501d6c8f866"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a09a032f8e1e77a3afc0b7df115a773e1"><td class="memTemplParams" colspan="2">template&lt;typename Cleanup_func &gt; </td></tr>
<tr class="memitem:a09a032f8e1e77a3afc0b7df115a773e1"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1util.html#ab22fd89e165a9e6deaa174bc0dfdc8de">Auto_cleanup</a>&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a09a032f8e1e77a3afc0b7df115a773e1">setup_auto_cleanup</a> (const Cleanup_func &amp;func)</td></tr>
<tr class="memdesc:a09a032f8e1e77a3afc0b7df115a773e1"><td class="mdescLeft">&#160;</td><td class="mdescRight">Provides a way to execute arbitrary (cleanup) code at the exit of the current block.  <a href="namespaceflow_1_1util.html#a09a032f8e1e77a3afc0b7df115a773e1">More...</a><br /></td></tr>
<tr class="separator:a09a032f8e1e77a3afc0b7df115a773e1"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a34ed70fa4de81a4fdb9234bfb5a3a914"><td class="memTemplParams" colspan="2">template&lt;typename Minuend , typename Subtrahend &gt; </td></tr>
<tr class="memitem:a34ed70fa4de81a4fdb9234bfb5a3a914"><td class="memTemplItemLeft" align="right" valign="top">bool&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a34ed70fa4de81a4fdb9234bfb5a3a914">subtract_with_floor</a> (Minuend *minuend, const Subtrahend &amp;subtrahend, const Minuend &amp;floor=0)</td></tr>
<tr class="memdesc:a34ed70fa4de81a4fdb9234bfb5a3a914"><td class="mdescLeft">&#160;</td><td class="mdescRight">Performs <code>*minuend -= subtrahend</code>, subject to a floor of <code>floor</code>.  <a href="namespaceflow_1_1util.html#a34ed70fa4de81a4fdb9234bfb5a3a914">More...</a><br /></td></tr>
<tr class="separator:a34ed70fa4de81a4fdb9234bfb5a3a914"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a67eecb5096dabfaff3d02c419b304540"><td class="memTemplParams" colspan="2">template&lt;typename From , typename To &gt; </td></tr>
<tr class="memitem:a67eecb5096dabfaff3d02c419b304540"><td class="memTemplItemLeft" align="right" valign="top">size_t&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a67eecb5096dabfaff3d02c419b304540">size_unit_convert</a> (From num_froms)</td></tr>
<tr class="memdesc:a67eecb5096dabfaff3d02c419b304540"><td class="mdescLeft">&#160;</td><td class="mdescRight">Answers the question <em>what's the smallest integer number of <code>To</code>s sufficient to verbatim store the given number of <code>From</code>s?</em>, where <code>From</code> and <code>To</code> are POD types.  <a href="namespaceflow_1_1util.html#a67eecb5096dabfaff3d02c419b304540">More...</a><br /></td></tr>
<tr class="separator:a67eecb5096dabfaff3d02c419b304540"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af92e6183c2071f4166d4b5a91f50d70c"><td class="memTemplParams" colspan="2">template&lt;typename T1 , typename ... T_rest&gt; </td></tr>
<tr class="memitem:af92e6183c2071f4166d4b5a91f50d70c"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#af92e6183c2071f4166d4b5a91f50d70c">feed_args_to_ostream</a> (std::ostream *os, T1 const &amp;ostream_arg1, T_rest const &amp;... remaining_ostream_args)</td></tr>
<tr class="memdesc:af92e6183c2071f4166d4b5a91f50d70c"><td class="mdescLeft">&#160;</td><td class="mdescRight">"Induction step" version of variadic function template that simply outputs arguments 2+ via <code>&lt;&lt;</code> to the given <code>ostream</code>, in the order given.  <a href="namespaceflow_1_1util.html#af92e6183c2071f4166d4b5a91f50d70c">More...</a><br /></td></tr>
<tr class="separator:af92e6183c2071f4166d4b5a91f50d70c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3ce0e3794a3a84dd26b4aa7b013f6276"><td class="memTemplParams" colspan="2">template&lt;typename T &gt; </td></tr>
<tr class="memitem:a3ce0e3794a3a84dd26b4aa7b013f6276"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a3ce0e3794a3a84dd26b4aa7b013f6276">feed_args_to_ostream</a> (std::ostream *os, T const &amp;only_ostream_arg)</td></tr>
<tr class="memdesc:a3ce0e3794a3a84dd26b4aa7b013f6276"><td class="mdescLeft">&#160;</td><td class="mdescRight">"Induction base" for a variadic function template, this simply outputs given item to given <code>ostream</code> via <code>&lt;&lt;</code>.  <a href="namespaceflow_1_1util.html#a3ce0e3794a3a84dd26b4aa7b013f6276">More...</a><br /></td></tr>
<tr class="separator:a3ce0e3794a3a84dd26b4aa7b013f6276"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8afd30c50bcd670d45442df49d1da484"><td class="memTemplParams" colspan="2">template&lt;typename ... T&gt; </td></tr>
<tr class="memitem:a8afd30c50bcd670d45442df49d1da484"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484">ostream_op_to_string</a> (std::string *target_str, T const &amp;... ostream_args)</td></tr>
<tr class="memdesc:a8afd30c50bcd670d45442df49d1da484"><td class="mdescLeft">&#160;</td><td class="mdescRight">Writes to the specified string, as if the given arguments were each passed, via <code>&lt;&lt;</code> in sequence, to an <code>ostringstream</code>, and then the result were appended to the aforementioned string variable.  <a href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484">More...</a><br /></td></tr>
<tr class="separator:a8afd30c50bcd670d45442df49d1da484"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a685b86585da2fa5186f51854e7ae1561"><td class="memTemplParams" colspan="2">template&lt;typename ... T&gt; </td></tr>
<tr class="memitem:a685b86585da2fa5186f51854e7ae1561"><td class="memTemplItemLeft" align="right" valign="top">std::string&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a685b86585da2fa5186f51854e7ae1561">ostream_op_string</a> (T const &amp;... ostream_args)</td></tr>
<tr class="memdesc:a685b86585da2fa5186f51854e7ae1561"><td class="mdescLeft">&#160;</td><td class="mdescRight">Equivalent to <a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484" title="Writes to the specified string, as if the given arguments were each passed, via &lt;&lt; in sequence,...">ostream_op_to_string()</a> but returns a new <code>string</code> by value instead of writing to the caller's <code>string</code>.  <a href="namespaceflow_1_1util.html#a685b86585da2fa5186f51854e7ae1561">More...</a><br /></td></tr>
<tr class="separator:a685b86585da2fa5186f51854e7ae1561"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0a873d1abeac7a29822e940adf4f06c9"><td class="memTemplParams" colspan="2">template&lt;typename Map , typename Sequence &gt; </td></tr>
<tr class="memitem:a0a873d1abeac7a29822e940adf4f06c9"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a0a873d1abeac7a29822e940adf4f06c9">sequence_to_inverted_lookup_map</a> (Sequence const &amp;src_seq, Map *target_map, const Function&lt; typename Map::mapped_type(size_t)&gt; &amp;idx_to_map_val_func)</td></tr>
<tr class="memdesc:a0a873d1abeac7a29822e940adf4f06c9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Similar to the 2-arg overload of <a class="el" href="namespaceflow_1_1util.html#a0a873d1abeac7a29822e940adf4f06c9" title="Similar to the 2-arg overload of sequence_to_inverted_lookup_map() but with the ability to store a va...">sequence_to_inverted_lookup_map()</a> but with the ability to store a value based on the index into the input sequence instead of that index itself.  <a href="namespaceflow_1_1util.html#a0a873d1abeac7a29822e940adf4f06c9">More...</a><br /></td></tr>
<tr class="separator:a0a873d1abeac7a29822e940adf4f06c9"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a002c9a2f7629dfe3fdfa5632eda30dbd"><td class="memTemplParams" colspan="2">template&lt;typename Map , typename Sequence &gt; </td></tr>
<tr class="memitem:a002c9a2f7629dfe3fdfa5632eda30dbd"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a002c9a2f7629dfe3fdfa5632eda30dbd">sequence_to_inverted_lookup_map</a> (Sequence const &amp;src_seq, Map *target_map)</td></tr>
<tr class="memdesc:a002c9a2f7629dfe3fdfa5632eda30dbd"><td class="mdescLeft">&#160;</td><td class="mdescRight">Given a generic sequence (integer -&gt; object) generates a generic map (object -&gt; integer) providing inverse lookup.  <a href="namespaceflow_1_1util.html#a002c9a2f7629dfe3fdfa5632eda30dbd">More...</a><br /></td></tr>
<tr class="separator:a002c9a2f7629dfe3fdfa5632eda30dbd"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa132928b364caefca5c3821e019924bf"><td class="memTemplParams" colspan="2">template&lt;typename Const_buffer_sequence &gt; </td></tr>
<tr class="memitem:aa132928b364caefca5c3821e019924bf"><td class="memTemplItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf">buffers_to_ostream</a> (std::ostream &amp;os, const Const_buffer_sequence &amp;data, const std::string &amp;indentation, size_t bytes_per_line=0)</td></tr>
<tr class="memdesc:aa132928b364caefca5c3821e019924bf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Writes a multi- or single-line string representation of the provided binary data to an output stream, complete with a printable and hex versions of each byte.  <a href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf">More...</a><br /></td></tr>
<tr class="separator:aa132928b364caefca5c3821e019924bf"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a16357344c21456b86b7de3085e2661a2"><td class="memTemplParams" colspan="2">template&lt;typename Const_buffer_sequence &gt; </td></tr>
<tr class="memitem:a16357344c21456b86b7de3085e2661a2"><td class="memTemplItemLeft" align="right" valign="top">std::string&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a16357344c21456b86b7de3085e2661a2">buffers_dump_string</a> (const Const_buffer_sequence &amp;data, const std::string &amp;indentation, size_t bytes_per_line=0)</td></tr>
<tr class="memdesc:a16357344c21456b86b7de3085e2661a2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Identical to <a class="el" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf" title="Writes a multi- or single-line string representation of the provided binary data to an output stream,...">buffers_to_ostream()</a> but returns an <code>std::string</code> instead of writing to a given <code>ostream</code>.  <a href="namespaceflow_1_1util.html#a16357344c21456b86b7de3085e2661a2">More...</a><br /></td></tr>
<tr class="separator:a16357344c21456b86b7de3085e2661a2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a18a29d6a6e65c3b96c52b5cad5971266"><td class="memTemplParams" colspan="2">template&lt;typename Enum &gt; </td></tr>
<tr class="memitem:a18a29d6a6e65c3b96c52b5cad5971266"><td class="memTemplItemLeft" align="right" valign="top">Enum&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1util.html#a18a29d6a6e65c3b96c52b5cad5971266">istream_to_enum</a> (std::istream *is_ptr, Enum enum_default, Enum enum_sentinel, bool accept_num_encoding=true, bool case_sensitive=false, Enum enum_lowest=Enum(0))</td></tr>
<tr class="memdesc:a18a29d6a6e65c3b96c52b5cad5971266"><td class="mdescLeft">&#160;</td><td class="mdescRight">Deserializes an <code>enum class</code> value from a standard input stream.  <a href="namespaceflow_1_1util.html#a18a29d6a6e65c3b96c52b5cad5971266">More...</a><br /></td></tr>
<tr class="separator:a18a29d6a6e65c3b96c52b5cad5971266"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >Flow module containing miscellaneous general-use facilities that don't fit into any other Flow module. </p>
<p >Each symbol therein is typically used by at least 1 other Flow module; but all public symbols (except ones under a detail/ subdirectory) are intended for use by Flow user as well.</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000073">Todo:</a></b></dt><dd>Since Flow gained its first users beyond the original author, some Flow-adjacent code has been written from which Flow can benefit, including additions to <a class="el" href="namespaceflow_1_1util.html" title="Flow module containing miscellaneous general-use facilities that don&#39;t fit into any other Flow module...">flow::util</a> module. (Flow itself continued to be developed, but some features were added elsewhere for expediency; this is a reminder to factor them out into Flow for the benefit of all.) Some features to migrate here might be: conversion between boost.chrono and std.chrono types; (add more here). </dd></dl>
</div><h2 class="groupheader">Typedef Documentation</h2>
<a id="af09888b3a8feaff209b6625e493bc338" name="af09888b3a8feaff209b6625e493bc338"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af09888b3a8feaff209b6625e493bc338">&#9670;&nbsp;</a></span>Blob</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">flow::util::Blob</a> = typedef <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html">Blob_with_log_context</a>&lt;&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>A concrete <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html" title="Basic_blob that works in regular heap (and is itself placed in heap or stack) and memorizes a log::Lo...">Blob_with_log_context</a> that compile-time-disables <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a0044410b7d1f541978a309f02b2739d3" title="Applicable to !zero() blobs, this returns an identical Basic_blob that shares (co-owns) *this allocat...">Basic_blob::share()</a> and the sharing API derived from it. </p>
<p >It is likely the user will refer to <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338" title="A concrete Blob_with_log_context that compile-time-disables Basic_blob::share() and the sharing API d...">Blob</a> (or <a class="el" href="namespaceflow_1_1util.html#a164f043f9edc5e5ec8fc99a0e4eb9064" title="A concrete Blob_with_log_context that compile-time-enables Basic_blob::share() and the sharing API de...">Sharing_blob</a>) rather than <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html" title="Basic_blob that works in regular heap (and is itself placed in heap or stack) and memorizes a log::Lo...">Blob_with_log_context</a>.</p>
<dl class="section see"><dt>See also</dt><dd>Also consider <a class="el" href="namespaceflow_1_1util.html#a2c085aa47872fe7e4dbba0703e23923c" title="Short-hand for a Basic_blob that allocates/deallocates in regular heap and is itself assumed to be st...">Blob_sans_log_context</a>. </dd></dl>

</div>
</div>
<a id="a2c085aa47872fe7e4dbba0703e23923c" name="a2c085aa47872fe7e4dbba0703e23923c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a2c085aa47872fe7e4dbba0703e23923c">&#9670;&nbsp;</a></span>Blob_sans_log_context</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a2c085aa47872fe7e4dbba0703e23923c">flow::util::Blob_sans_log_context</a> = typedef <a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt;&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for a <a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> that allocates/deallocates in regular heap and is itself assumed to be stored in heap or on stack; sharing feature compile-time-disabled (with perf boost as a result). </p>
<dl class="section see"><dt>See also</dt><dd>Consider also <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338" title="A concrete Blob_with_log_context that compile-time-disables Basic_blob::share() and the sharing API d...">Blob</a> which takes a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">log::Logger</a> at construction and stores it; so it is not necessary to provide one to each individual API one wants to <a class="el" href="namespaceflow_1_1log.html" title="Flow module providing logging functionality.">log</a>. It also adds logging where it is normally not possible (as of this writing at least the dtor). See <a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> doc header "Logging" section for brief discussion of trade-offs. </dd></dl>

</div>
</div>
<a id="a5d2247b715da63e4b960909561b90ae7" name="a5d2247b715da63e4b960909561b90ae7"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a5d2247b715da63e4b960909561b90ae7">&#9670;&nbsp;</a></span>Lock_guard</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Mutex &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a5d2247b715da63e4b960909561b90ae7">flow::util::Lock_guard</a> = typedef boost::unique_lock&lt;Mutex&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for advanced-capability RAII lock guard for any mutex, ensuring exclusive ownership of that mutex. </p>
<p >Note the advanced API available for the underlying type: it is possible to relinquish ownership without unlocking, gain ownership of a locked mutex; and so on.</p>
<dl class="section see"><dt>See also</dt><dd>To grab shared-level ownership of a shared-or-exclusive mutex: use <a class="el" href="namespaceflow_1_1util.html#ac4f0492f15f46f70581feac50b9217ee" title="Short-hand for shared mode advanced-capability RAII lock guard, particuarly for Mutex_shared_non_recu...">Shared_lock_guard</a>.</dd></dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Mutex</td><td>A non-recursive or recursive mutex type. Recommend one of: <a class="el" href="namespaceflow_1_1util.html#add6ade273326f27eaf9bfd170a909626" title="Short-hand for non-reentrant, exclusive mutex. (&quot;Reentrant&quot; = one can lock an already-locked-in-that-...">Mutex_non_recursive</a>, <a class="el" href="namespaceflow_1_1util.html#a9c7a5df07c2e86c788de9e6bbaee77d5" title="Short-hand for reentrant, exclusive mutex.">Mutex_recursive</a>, <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">Mutex_shared_non_recursive</a>, <a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112" title="Short-hand for a mutex type equivalent to util::Mutex_shared_non_recursive – except that the lock/unl...">Mutex_noop_shared_non_recursive</a>. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a9495b3e37e9d27bcc7767a4b6ce87ff4" name="a9495b3e37e9d27bcc7767a4b6ce87ff4"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9495b3e37e9d27bcc7767a4b6ce87ff4">&#9670;&nbsp;</a></span>Lock_guard_non_recursive</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a9495b3e37e9d27bcc7767a4b6ce87ff4">flow::util::Lock_guard_non_recursive</a> = typedef boost::unique_lock&lt;<a class="el" href="namespaceflow_1_1util.html#add6ade273326f27eaf9bfd170a909626">Mutex_non_recursive</a>&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>(Deprecated given C++1x) Short-hand for advanced-capability RAII lock guard for <a class="el" href="namespaceflow_1_1util.html#add6ade273326f27eaf9bfd170a909626" title="Short-hand for non-reentrant, exclusive mutex. (&quot;Reentrant&quot; = one can lock an already-locked-in-that-...">Mutex_non_recursive</a> mutexes. </p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000077">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1util.html#a9495b3e37e9d27bcc7767a4b6ce87ff4" title="(Deprecated given C++1x) Short-hand for advanced-capability RAII lock guard for Mutex_non_recursive m...">Lock_guard_non_recursive</a> is deprecated, now that C++1x made the more flexible <code>Lock_guard&lt;Mutex_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually. </dd></dl>

</div>
</div>
<a id="add56211dee74c212c19028f1ded2a785" name="add56211dee74c212c19028f1ded2a785"></a>
<h2 class="memtitle"><span class="permalink"><a href="#add56211dee74c212c19028f1ded2a785">&#9670;&nbsp;</a></span>Lock_guard_noop_shared_non_recursive_ex</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#add56211dee74c212c19028f1ded2a785">flow::util::Lock_guard_noop_shared_non_recursive_ex</a> = typedef boost::unique_lock&lt;<a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112">Mutex_noop_shared_non_recursive</a>&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>(Deprecated given C++1x) Equivalent to <a class="el" href="namespaceflow_1_1util.html#a9df3cc2f3aec0c0353443b9d6c81e638" title="(Deprecated given C++1x) Short-hand for exclusive mode advanced-capability RAII lock guard for Mutex_...">Lock_guard_shared_non_recursive_ex</a> but applied to <a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112" title="Short-hand for a mutex type equivalent to util::Mutex_shared_non_recursive – except that the lock/unl...">Mutex_noop_shared_non_recursive</a>. </p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000082">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1util.html#add56211dee74c212c19028f1ded2a785" title="(Deprecated given C++1x) Equivalent to Lock_guard_shared_non_recursive_ex but applied to Mutex_noop_s...">Lock_guard_noop_shared_non_recursive_ex</a> is deprecated, now that C++1x made the more flexible <code>Lock_guard&lt;Mutex_noop_shared_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually. </dd></dl>

</div>
</div>
<a id="a9e5fae573be960434c4c9dacd48c9c11" name="a9e5fae573be960434c4c9dacd48c9c11"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9e5fae573be960434c4c9dacd48c9c11">&#9670;&nbsp;</a></span>Lock_guard_noop_shared_non_recursive_sh</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a9e5fae573be960434c4c9dacd48c9c11">flow::util::Lock_guard_noop_shared_non_recursive_sh</a> = typedef boost::shared_lock&lt;<a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112">Mutex_noop_shared_non_recursive</a>&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>(Deprecated given C++1x) Equivalent to <a class="el" href="namespaceflow_1_1util.html#a689388b6eb7e760933d99381d65cacca" title="(Deprecated given C++1x) Short-hand for shared mode advanced-capability RAII lock guard for Mutex_sha...">Lock_guard_shared_non_recursive_sh</a> but applied to <a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112" title="Short-hand for a mutex type equivalent to util::Mutex_shared_non_recursive – except that the lock/unl...">Mutex_noop_shared_non_recursive</a>. </p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000081">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1util.html#a9e5fae573be960434c4c9dacd48c9c11" title="(Deprecated given C++1x) Equivalent to Lock_guard_shared_non_recursive_sh but applied to Mutex_noop_s...">Lock_guard_noop_shared_non_recursive_sh</a> is deprecated, now that C++1x made the more flexible <code>Shared_lock_guard&lt;Mutex_noop_shared_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually. </dd></dl>

</div>
</div>
<a id="a015b84cfa3076b8e75d16ec44a5514a3" name="a015b84cfa3076b8e75d16ec44a5514a3"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a015b84cfa3076b8e75d16ec44a5514a3">&#9670;&nbsp;</a></span>Lock_guard_recursive</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a015b84cfa3076b8e75d16ec44a5514a3">flow::util::Lock_guard_recursive</a> = typedef boost::unique_lock&lt;<a class="el" href="namespaceflow_1_1util.html#a9c7a5df07c2e86c788de9e6bbaee77d5">Mutex_recursive</a>&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>(Deprecated given C++1x) Short-hand for advanced-capability RAII lock guard for <a class="el" href="namespaceflow_1_1util.html#a9c7a5df07c2e86c788de9e6bbaee77d5" title="Short-hand for reentrant, exclusive mutex.">Mutex_recursive</a> mutexes. </p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000078">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1util.html#a015b84cfa3076b8e75d16ec44a5514a3" title="(Deprecated given C++1x) Short-hand for advanced-capability RAII lock guard for Mutex_recursive mutex...">Lock_guard_recursive</a> is deprecated, now that C++1x made the more flexible <code>Lock_guard&lt;Mutex_recursive&gt;</code> possible. Remove it and all (outside) uses eventually. </dd></dl>

</div>
</div>
<a id="a9df3cc2f3aec0c0353443b9d6c81e638" name="a9df3cc2f3aec0c0353443b9d6c81e638"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9df3cc2f3aec0c0353443b9d6c81e638">&#9670;&nbsp;</a></span>Lock_guard_shared_non_recursive_ex</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a9df3cc2f3aec0c0353443b9d6c81e638">flow::util::Lock_guard_shared_non_recursive_ex</a> = typedef boost::unique_lock&lt;<a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421">Mutex_shared_non_recursive</a>&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>(Deprecated given C++1x) Short-hand for <em>exclusive mode</em> advanced-capability RAII lock guard for <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">Mutex_shared_non_recursive</a> mutexes. </p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000080">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1util.html#a9df3cc2f3aec0c0353443b9d6c81e638" title="(Deprecated given C++1x) Short-hand for exclusive mode advanced-capability RAII lock guard for Mutex_...">Lock_guard_shared_non_recursive_ex</a> is deprecated, now that C++1x made the more flexible <code>Lock_guard&lt;Mutex_shared_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually. </dd></dl>

</div>
</div>
<a id="a689388b6eb7e760933d99381d65cacca" name="a689388b6eb7e760933d99381d65cacca"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a689388b6eb7e760933d99381d65cacca">&#9670;&nbsp;</a></span>Lock_guard_shared_non_recursive_sh</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a689388b6eb7e760933d99381d65cacca">flow::util::Lock_guard_shared_non_recursive_sh</a> = typedef boost::shared_lock&lt;<a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421">Mutex_shared_non_recursive</a>&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>(Deprecated given C++1x) Short-hand for <em>shared mode</em> advanced-capability RAII lock guard for <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">Mutex_shared_non_recursive</a> mutexes. </p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000079">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1util.html#a689388b6eb7e760933d99381d65cacca" title="(Deprecated given C++1x) Short-hand for shared mode advanced-capability RAII lock guard for Mutex_sha...">Lock_guard_shared_non_recursive_sh</a> is deprecated, now that C++1x made the more flexible <code>Shared_lock_guard&lt;Mutex_shared_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually. </dd></dl>

</div>
</div>
<a id="aeee121f0277371517fd2f5c3a20d8112" name="aeee121f0277371517fd2f5c3a20d8112"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aeee121f0277371517fd2f5c3a20d8112">&#9670;&nbsp;</a></span>Mutex_noop_shared_non_recursive</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#aeee121f0277371517fd2f5c3a20d8112">flow::util::Mutex_noop_shared_non_recursive</a> = typedef boost::null_mutex</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for a mutex type equivalent to <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">util::Mutex_shared_non_recursive</a> &ndash; except that the lock/unlock mutex ops all do nothing. </p>
<p >One can parameterize templates accordingly; so that an algorithm can be generically written to work in both single- and multi-threaded contexts without branching into 2 code paths, yet avoid the unnecessary actual locking in the former case. </p>

</div>
</div>
<a id="a62b5ba6d6a549ac20e2c055e72bef421" name="a62b5ba6d6a549ac20e2c055e72bef421"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a62b5ba6d6a549ac20e2c055e72bef421">&#9670;&nbsp;</a></span>Mutex_shared_non_recursive</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421">flow::util::Mutex_shared_non_recursive</a> = typedef boost::shared_mutex</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for non-reentrant, shared-or-exclusive mutex. </p>
<p >When locking one of these, choose one of: <code>Lock_guard&lt;Mutex_shared_non_recursive&gt;</code>, <code>Shared_lock_guard&lt;Mutex_shared_non_recursive&gt;</code>. The level of locking acquired (shared vs. exclusive) depends on which you chose and is thus highly significant.</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000076">Todo:</a></b></dt><dd>Consider changing <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">util::Mutex_shared_non_recursive</a> from <code>boost::shared_mutex</code> to <code>std::shared_mutex</code>, as the former has a long-standing unresolved ticket about its impl being slow and/or outdated (as of Boost-1.80). However see also the note on <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">util::Mutex_shared_non_recursive</a> that explains why it might be best to avoid this type of mutex altogether in the first place (in most cases).</dd></dl>
<h3>When to use versus <a class="el" href="namespaceflow_1_1util.html#add6ade273326f27eaf9bfd170a909626" title="Short-hand for non-reentrant, exclusive mutex. (&quot;Reentrant&quot; = one can lock an already-locked-in-that-...">Mutex_non_recursive</a></h3>
<p >Experts suggest fairly strongly that one should be very wary about using a shared mutex, over a simple non-recursive exclusive mutex, in almost any practical application. The reason there's a trade-off at all is that a <a class="el" href="namespaceflow_1_1util.html#add6ade273326f27eaf9bfd170a909626" title="Short-hand for non-reentrant, exclusive mutex. (&quot;Reentrant&quot; = one can lock an already-locked-in-that-...">Mutex_non_recursive</a> is extremely fast to lock and unlock; the entire perf cost is in waiting for another thread to unlock first; so without contention it's almost <em>free</em>. In contrast apparently any real impl of <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">Mutex_shared_non_recursive</a> is much slower to lock/unlock. The trade-off is against allowing reads to proceed in parallel; but experts say this is "worth it" only when these read critical sections are lengthy and very frequently invoked. So, for example, if the lock/unlock is around an <code>unordered_map</code> lookup with a quick hashing function, it would be quite difficult to induce enough lock contention to make a shared mutex better than an exclusive one. (Note this is assuming even no perf issue with <code>boost::shared_mutex</code> specifically.) </p>

</div>
</div>
<a id="aafa03984c5012ef7db2e7d01b6909a83" name="aafa03984c5012ef7db2e7d01b6909a83"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aafa03984c5012ef7db2e7d01b6909a83">&#9670;&nbsp;</a></span>Scheduled_task</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#aafa03984c5012ef7db2e7d01b6909a83">flow::util::Scheduled_task</a> = typedef Function&lt;void (bool short_fire)&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for tasks that can be scheduled/fired by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> and similar. </p>
<p ><code>short_fire</code> shall be set to <code>false</code> if the task executed based on its scheduled time; <code>true</code> if it is fired early due to <a class="el" href="namespaceflow_1_1util.html#abe8d04de7ba9ac770112ee585b77cd20" title="Attempts to reschedule a previously scheduled (by schedule_task_from_now() or similar) task to fire i...">scheduled_task_short_fire()</a>. </p>

</div>
</div>
<a id="add471ec4a0f0b76793c9c84adb4916d5" name="add471ec4a0f0b76793c9c84adb4916d5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#add471ec4a0f0b76793c9c84adb4916d5">&#9670;&nbsp;</a></span>Scheduled_task_const_handle</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#add471ec4a0f0b76793c9c84adb4916d5">flow::util::Scheduled_task_const_handle</a> = typedef boost::shared_ptr&lt;const Scheduled_task_handle_state&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Equivalent to <code>Scheduled_task_handle</code> but refers to immutable version of a task. </p>
<p >One can safely construct a <code>Scheduled_task_const_handle</code> directly from <code>Scheduled_task_handle</code> (but not vice versa; nor would that compile without some kind of frowned-upon <code>const_cast</code> or equivalent). </p>

</div>
</div>
<a id="aa0d10f5a906b3229f48979aa43e9ff7e" name="aa0d10f5a906b3229f48979aa43e9ff7e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa0d10f5a906b3229f48979aa43e9ff7e">&#9670;&nbsp;</a></span>Scheduled_task_handle</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">flow::util::Scheduled_task_handle</a> = typedef boost::shared_ptr&lt;Scheduled_task_handle_state&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Black-box type that represents a handle to a scheduled task as scheduled by <a class="el" href="namespaceflow_1_1util.html#aad8c8f7335eb892350dc386cb4be397e" title="Identical to schedule_task_from_now() except the time is specified in absolute terms.">schedule_task_at()</a> or <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar, which can be (optionally) used to control the scheduled task after it has been thus scheduled. </p>
<p >Special value <code><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e" title="Black-box type that represents a handle to a scheduled task as scheduled by schedule_task_at() or sch...">Scheduled_task_handle()</a></code> represents an invalid task and can be used as a sentinel, as with a null pointer.</p>
<p >Values of this type are to be passed around by value, not reference. They are light-weight. Officially, passing it by reference results in undefined behavior. Unofficially, it will probably work (just haven't thought super-hard about it to make sure) but will bring no performance benefit. </p>

</div>
</div>
<a id="ac4f0492f15f46f70581feac50b9217ee" name="ac4f0492f15f46f70581feac50b9217ee"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac4f0492f15f46f70581feac50b9217ee">&#9670;&nbsp;</a></span>Shared_lock_guard</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Shared_mutex &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#ac4f0492f15f46f70581feac50b9217ee">flow::util::Shared_lock_guard</a> = typedef boost::shared_lock&lt;Shared_mutex&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for <em>shared mode</em> advanced-capability RAII lock guard, particuarly for <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">Mutex_shared_non_recursive</a> mutexes. </p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Shared_mutex</td><td>Typically <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">Mutex_shared_non_recursive</a>, but any mutex type with that both-exclusive-and-shared API will work. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a164f043f9edc5e5ec8fc99a0e4eb9064" name="a164f043f9edc5e5ec8fc99a0e4eb9064"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a164f043f9edc5e5ec8fc99a0e4eb9064">&#9670;&nbsp;</a></span>Sharing_blob</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a164f043f9edc5e5ec8fc99a0e4eb9064">flow::util::Sharing_blob</a> = typedef <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html">Blob_with_log_context</a>&lt;true&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>A concrete <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html" title="Basic_blob that works in regular heap (and is itself placed in heap or stack) and memorizes a log::Lo...">Blob_with_log_context</a> that compile-time-enables <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a0044410b7d1f541978a309f02b2739d3" title="Applicable to !zero() blobs, this returns an identical Basic_blob that shares (co-owns) *this allocat...">Basic_blob::share()</a> and the sharing API derived from it. </p>
<p >It is likely the user will refer to <a class="el" href="namespaceflow_1_1util.html#a164f043f9edc5e5ec8fc99a0e4eb9064" title="A concrete Blob_with_log_context that compile-time-enables Basic_blob::share() and the sharing API de...">Sharing_blob</a> (or <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338" title="A concrete Blob_with_log_context that compile-time-disables Basic_blob::share() and the sharing API d...">Blob</a>) rather than <a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html" title="Basic_blob that works in regular heap (and is itself placed in heap or stack) and memorizes a log::Lo...">Blob_with_log_context</a>.</p>
<dl class="section see"><dt>See also</dt><dd>Also consider <a class="el" href="namespaceflow_1_1util.html#a0edd9dd6bf51e7457477123b419f5bf6" title="Identical to Blob_sans_log_context but with sharing feature compile-time-enabled.">Sharing_blob_sans_log_context</a>. </dd></dl>

</div>
</div>
<a id="a0edd9dd6bf51e7457477123b419f5bf6" name="a0edd9dd6bf51e7457477123b419f5bf6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0edd9dd6bf51e7457477123b419f5bf6">&#9670;&nbsp;</a></span>Sharing_blob_sans_log_context</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#a0edd9dd6bf51e7457477123b419f5bf6">flow::util::Sharing_blob_sans_log_context</a> = typedef <a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt;std::allocator&lt;<a class="el" href="namespaceflow.html#ae02da22c4a101eaab447511c905e4f32">uint8_t</a>&gt;, true&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Identical to <a class="el" href="namespaceflow_1_1util.html#a2c085aa47872fe7e4dbba0703e23923c" title="Short-hand for a Basic_blob that allocates/deallocates in regular heap and is itself assumed to be st...">Blob_sans_log_context</a> but with sharing feature compile-time-enabled. </p>
<p >The latter fact implies a small perf hit; see details in <a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> doc header.</p>
<dl class="section see"><dt>See also</dt><dd>Consider also <a class="el" href="namespaceflow_1_1util.html#a164f043f9edc5e5ec8fc99a0e4eb9064" title="A concrete Blob_with_log_context that compile-time-enables Basic_blob::share() and the sharing API de...">Sharing_blob</a>; and see <a class="el" href="namespaceflow_1_1util.html#a2c085aa47872fe7e4dbba0703e23923c" title="Short-hand for a Basic_blob that allocates/deallocates in regular heap and is itself assumed to be st...">Blob_sans_log_context</a> similar "See" note for more info as to why. </dd></dl>

</div>
</div>
<a id="ac3e89a8a271b0ddc76ac2a0ce488dea4" name="ac3e89a8a271b0ddc76ac2a0ce488dea4"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac3e89a8a271b0ddc76ac2a0ce488dea4">&#9670;&nbsp;</a></span>Task_engine</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">flow::util::Task_engine</a> = typedef boost::asio::io_context</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for boost.asio event service, the central class of boost.asio. </p>
<h3>Naming</h3>
<p >The reasons for the rename &ndash; as opposed to simply calling it <code>Io_service</code> (historically it was indeed so named) &ndash; are as follows. To start, a later version of Boost (to which we eventually moved) realigned boost.asio's API to match the feedback boost.asio received when submitted as a candidate for inclusion into the official STL (sometime after C++17); in this reorg they renamed it from <code>io_service</code> to <code>io_context</code>. That's not the actual reason but more of a symptom of similar reasoning to the following:</p><ul>
<li>"Service" sounds like something that has its own thread(s) perhaps, which <code>io_service</code> actually doesn't; it <em>can</em> (and typically is) used to take over at least one thread, but that's not a part of its "essence," so to speak. I've noticed that when boost.asio neophytes see "service" they intuitively draw incorrect assumptions about what it does, and then one must repeatedly dash those assumptions.</li>
<li>Furthermore (though apparently boost.asio guys didn't agree or didn't agree strongly enough) "I/O" implies an <code>io_service</code> is all about working with various input/output (especially networking). While it's true that roughly 50% of the utility of boost.asio is its portable sockets/networking API, the other 50% is about its ability to flexibly execute user tasks in various threads; and, indeed, <code>io_service</code> <em>itself</em> is more about the latter 50% rather than the former. Its two most basic and arguably oft-used features are simply <code>io_service::post()</code> (which executes the given task ASAP); and the <code>basic_waitable_timer</code> set of classes (which execute task at some specified point in the future). Note these have nothing to do with networking or I/O of any kind. The I/O comes from the "I/O object" classes/etc., such as <code>tcp::socket</code>, but those are <em>not</em> <code>io_service</code>; they merely work together with it to execute the user-specified success/failure handlers.</li>
</ul>
<p >So, neither "I/O" nor "service" is accurate. To fix both, then, we used this rename reasoning:</p><ul>
<li>"I/O" can be replaced by the notion of it executing "tasks." boost.asio doesn't use or define the "task" term, sticking to "handler" or "functor" or "function," but we feel it's a reasonable term in this context. (Function, etc., doesn't cover all possibilities. Handler is OK, but when it's not in response to any event &ndash; as with vanilla <code>post()</code> &ndash; what is it handling?)</li>
<li>"Service" is trickier to replace. It's a battle between "too generic" and "too specific and therefore long to
    type." Plus there's the usual danger of accidentally overloading a term already used elsewhere nearby. Some ideas considered were: manager, engine, execution engine, queue, queues, context (which boost.asio chose), and various abbreviations thereof. Ultimately it came down to context vs. engine, and I chose engine because context is just a little vague, or it suggests an arbitrary grouping of things &ndash; whereas "engine" actually implies action: want to express this thing provides logical/algorithmic value as opposed to just bundling stuff together as "context" objects often do (e.g., "SSL context" in openssl). Indeed <code>io_service</code> does provide immense algorithmic value.<ul>
<li>Manager: generic but not bad; clashes with "Windows task manager" and such.</li>
<li>Execution engine: good but long.</li>
<li>Queue: early candidate, but at the very least it's not a <em>single</em> queue; if there are multiple threads <code>io_context::run()</code>ning then to the extent there are any queues there might be multiple.</li>
<li>Queues, qs: better... but having a thing called <code>Task_qs</code> &ndash; of which there could be multiple (plural) &ndash; was clumsy. (An early proof-of-concept used <code>Task_qs</code>; people were not fans.) </li>
</ul>
</li>
</ul>

</div>
</div>
<a id="af030c3119f060a9630afca31098a78a5" name="af030c3119f060a9630afca31098a78a5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af030c3119f060a9630afca31098a78a5">&#9670;&nbsp;</a></span>Thread</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">flow::util::Thread</a> = typedef boost::thread</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for standard thread class. </p>
<p >We use/encourage use of boost.thread threads (and other boost.thread facilities) over std.thread counterparts &ndash; simply because it tends to be more full-featured. However, reminder: boost.thread IS (API-wise at least) std.thread, plus more (advanced?) stuff. Generally, boost.thread-using code can be converted to std.thread with little pain, unless one of the "advanced?" features is used. </p>

</div>
</div>
<a id="ae7416d64d2989051104bb396e28e15e6" name="ae7416d64d2989051104bb396e28e15e6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae7416d64d2989051104bb396e28e15e6">&#9670;&nbsp;</a></span>Timer</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6">flow::util::Timer</a> = typedef boost::asio::basic_waitable_timer&lt;<a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00">Fine_clock</a>&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>boost.asio timer. </p>
<p >Can schedule a function to get called within a set amount of time or at a certain specific time relative to some Epoch.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> (and friends) for a simpler task-scheduling API (which internally uses this <code><a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>). The notes below still apply however. Please read them even if you won't use</code>Timer` directly.</dd></dl>
<p>Important: While one can schedule events using very precise units using <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">Fine_duration</a>, the timer may not actually have that resolution. That is, I may schedule something to happen in 1 millisecond and then measure the time passed, using a high-res clock like <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00" title="Clock used for delicate time measurements, such that the now() method gets the current time relative ...">Fine_clock</a>, and discover that the wait was actually 15 milliseconds. This is not a problem for most timers. (In Flow itself, the most advanced use of timers by far is in <a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">flow::net_flow</a>. Timers used in <a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">flow::net_flow</a> &ndash; delayed ACK timer, Drop Timer, simulated latency timer &ndash; typically are for <code>n x 50</code> milliseconds time periods or coarser.) However that may not be the case for all timers. (In particular, <a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">flow::net_flow</a> packet pacing may use finer time periods.)</p>
<dl class="section note"><dt>Note</dt><dd>The <a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">flow::net_flow</a> references in the present doc header speak of internal implementation details &ndash; not of interest to the <code><a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">net_flow</a></code> <em>user</em>. I leave them in this public doc header for practical purposes, as examples needed to discuss some Inside-Baseball topics involved.</dd></dl>
<p>So I looked into what boost.asio provides. <code>deadline_timer</code> uses the system clock (<code>universal_time()</code>) as the time reference, while <code>basic_waitable_timer&lt;Fine_clock&gt;</code> uses the high-resolution clock (see <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00" title="Clock used for delicate time measurements, such that the now() method gets the current time relative ...">Fine_clock</a>). I tested both (using <code>wait()</code>s of various lengths and using <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00" title="Clock used for delicate time measurements, such that the now() method gets the current time relative ...">Fine_clock</a> to measure duration) and observed the following resolutions on certain OS (not listing the hardware):</p>
<ul>
<li>Linux (2.6.x kernel): sub-2 millisecond resolution, with some variance. (Note: This Linux's <code>glibc</code> is too old to provide the <code>timerfd</code> API, therefore Boost falls back to using <code>epoll_wait()</code> directly; on a newer Linux this may get better results.)</li>
<li>Windows 7: 15 millisecond resolution, with little variance.</li>
<li>macOS: untested. <dl class="todo"><dt><b><a class="el" href="todo.html#_todo000074">Todo:</a></b></dt><dd>Test macOS timer fidelity.</dd></dl>
</li>
</ul>
<p >These results were observed for BOTH <code>deadline_timer</code> and <code>basic_waitable_timer&lt;Fine_clock&gt;</code> in Boost 1.50. Thus, there was no resolution advantage to using the latter &ndash; only an interface advantage. Conclusion: we'd be well-advised not to rely on anything much smaller than 20 milliseconds when scheduling timer events. One technique might be, given any time T &lt; 20 ms, to assume T = 0 (i.e., execute immediately). This may or may not be appropriate depending on the situation.</p>
<p >However, using <code>basic_waitable_timer&lt;Fine_clock&gt;</code> may get an additional nice property: <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00" title="Clock used for delicate time measurements, such that the now() method gets the current time relative ...">Fine_clock</a> always goes forward and cannot be affected by NTP or user changes. <code>deadline_timer</code> may or may not be affected by such tomfoolery (untested, but the potential is clearly there). Therefore we do the best we can by using the <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00" title="Clock used for delicate time measurements, such that the now() method gets the current time relative ...">Fine_clock</a>-based timer.</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000075">Todo:</a></b></dt><dd>Upgrade to newer Boost and keep testing timer resolutions on the above and other OS versions. Update: As of this writing we are on Boost 1.74 now. Needless to say, it is time to reassess the above, as it has been years since 1.50 &ndash; and we had been on 1.63 and 1.66 for long period of time, let alone 1.74. Update: No changes with Boost 1.75, the newest version as of this writing.</dd></dl>
<dl class="section note"><dt>Note</dt><dd>One annoying, though fully documented, "feature" of this and all boost.asio timers is that <code>cancel()</code>ing it does not always cause the handler to fire with <code>operation_aborted</code> error code. Sometimes it was already "just
about" to fire at <code>cancel()</code> time, so the handler will run with no error code regardless of the <code>cancel()</code>. Personally I have never once found this behavior useful, and there is much code currently written to work around this "feature." Furthermore, even a "successful" cancel still runs the handler but with <code>operation_aborted</code>; 99.999% of the time one would want to just not run it at all. Finally, in many cases, even having to create a timer object (and then the multiple steps required to actually schedule a thing) feels like more boiler-plate than should be necessary. To avoid all of these usability issues, see <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> (and similar), which is a facility that wraps <code>Timer</code> for a boiler-plate-free experience sufficient in the majority of practical situations. <code>Timer</code> is to be used directly when that simpler facility is insufficient.</dd>
<dd>
<code>b_w_t&lt;Fine_clock&gt;</code> happens to equal <code>boost::asio::high_resolution_timer</code>. We chose to alias in terms of <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00" title="Clock used for delicate time measurements, such that the now() method gets the current time relative ...">Fine_clock</a> merely to ensure that <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">Fine_duration</a> is one-to-one compatible with it, as it is defined in terms of <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00" title="Clock used for delicate time measurements, such that the now() method gets the current time relative ...">Fine_clock</a> also. </dd></dl>

</div>
</div>
<h2 class="groupheader">Function Documentation</h2>
<a id="a0955a29930075ac1fe393896c089b911" name="a0955a29930075ac1fe393896c089b911"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0955a29930075ac1fe393896c089b911">&#9670;&nbsp;</a></span>beautify_chrono_ostream()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::util::beautify_chrono_ostream </td>
          <td>(</td>
          <td class="paramtype">std::ostream *&#160;</td>
          <td class="paramname"><em>os</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Sets certain <code>chrono</code>-related formatting on the given <code>ostream</code> that results in a consistent, desirable output of <code>duration</code>s and certain types of <code>time_point</code>s. </p>
<p >As of this writing this includes enabling short unit format (e.g., "ms" instead of "milliseconds") and avoiding Unicode characters (the Greek letter for micro becomes a similar-looking "u" instead).</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1log.html#aaaaa1dcbf7c8dc99aceb2b6c217187fc" title="Sets certain chrono-related formatting on the given Logger in the current thread that results in a co...">log::beautify_chrono_logger_this_thread()</a> to affect a Logger directly. </dd>
<dd>
<a class="el" href="namespaceflow_1_1async.html" title="Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-tas...">flow::async</a> in which new threads are set to use this formatting automatically. However you'll want to do this explicitly for the startup thread.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>The stream to affect. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="af567381736851969f6e8812c54404028" name="af567381736851969f6e8812c54404028"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af567381736851969f6e8812c54404028">&#9670;&nbsp;</a></span>blobs_sharing()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Allocator , bool S_SHARING_ALLOWED&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">bool blobs_sharing </td>
          <td>(</td>
          <td class="paramtype">const <a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt; Allocator, S_SHARING_ALLOWED &gt; &amp;&#160;</td>
          <td class="paramname"><em>blob1</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt; Allocator, S_SHARING_ALLOWED &gt; &amp;&#160;</td>
          <td class="paramname"><em>blob2</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns <code>true</code> if and only if both given objects are not <code>zero() == true</code>, and they either co-own a common underlying buffer, or <em>are</em> the same object. </p>
<p >Note: by the nature of <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a0044410b7d1f541978a309f02b2739d3" title="Applicable to !zero() blobs, this returns an identical Basic_blob that shares (co-owns) *this allocat...">Basic_blob::share()</a>, a <code>true</code> returned value is orthogonal to whether <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a64ea173065830ef1a744458a7d05b833" title="Returns the offset between begin() and the start of the internally allocated buffer.">Basic_blob::start()</a> and <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a8c04d217b83800f818c794da17dc8e4b" title="Returns number of elements stored, namely end() - begin().">Basic_blob::size()</a> values are respectively equal; <code>true</code> may be returned even if their [<code>begin()</code>, <code>end()</code>) ranges don't overlap at all &ndash; as long as the allocated buffer is co-owned by the 2 <code><a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a></code>s.</p>
<p >If <code>&amp;blob1 != &amp;blob2</code>, <code>true</code> indicates <code>blob1</code> was obtained from <code>blob2</code> via a chain of <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a0044410b7d1f541978a309f02b2739d3" title="Applicable to !zero() blobs, this returns an identical Basic_blob that shares (co-owns) *this allocat...">Basic_blob::share()</a> (or wrapper thereof) calls, or vice versa.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">blob1</td><td>Object. </td></tr>
    <tr><td class="paramname">blob2</td><td>Object. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Whether <code>blob1</code> and <code>blob2</code> both operate on the same underlying buffer. </dd></dl>

</div>
</div>
<a id="a16357344c21456b86b7de3085e2661a2" name="a16357344c21456b86b7de3085e2661a2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a16357344c21456b86b7de3085e2661a2">&#9670;&nbsp;</a></span>buffers_dump_string()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Const_buffer_sequence &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">std::string flow::util::buffers_dump_string </td>
          <td>(</td>
          <td class="paramtype">const Const_buffer_sequence &amp;&#160;</td>
          <td class="paramname"><em>data</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const std::string &amp;&#160;</td>
          <td class="paramname"><em>indentation</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>bytes_per_line</em> = <code>0</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Identical to <a class="el" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf" title="Writes a multi- or single-line string representation of the provided binary data to an output stream,...">buffers_to_ostream()</a> but returns an <code>std::string</code> instead of writing to a given <code>ostream</code>. </p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf" title="Writes a multi- or single-line string representation of the provided binary data to an output stream,...">buffers_to_ostream()</a> doc header for notes on performance and usability.</dd></dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Const_buffer_sequence</td><td>See <a class="el" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf" title="Writes a multi- or single-line string representation of the provided binary data to an output stream,...">buffers_to_ostream()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">data</td><td>See <a class="el" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf" title="Writes a multi- or single-line string representation of the provided binary data to an output stream,...">buffers_to_ostream()</a>. </td></tr>
    <tr><td class="paramname">indentation</td><td>See <a class="el" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf" title="Writes a multi- or single-line string representation of the provided binary data to an output stream,...">buffers_to_ostream()</a>. </td></tr>
    <tr><td class="paramname">bytes_per_line</td><td>See <a class="el" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf" title="Writes a multi- or single-line string representation of the provided binary data to an output stream,...">buffers_to_ostream()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Result string. </dd></dl>

</div>
</div>
<a id="aa132928b364caefca5c3821e019924bf" name="aa132928b364caefca5c3821e019924bf"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa132928b364caefca5c3821e019924bf">&#9670;&nbsp;</a></span>buffers_to_ostream()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Const_buffer_sequence &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">std::ostream &amp; flow::util::buffers_to_ostream </td>
          <td>(</td>
          <td class="paramtype">std::ostream &amp;&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const Const_buffer_sequence &amp;&#160;</td>
          <td class="paramname"><em>data</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const std::string &amp;&#160;</td>
          <td class="paramname"><em>indentation</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>bytes_per_line</em> = <code>0</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Writes a multi- or single-line string representation of the provided binary data to an output stream, complete with a printable and hex versions of each byte. </p>
<ul>
<li>Single-line mode is chosen by setting <code>bytes_per_line</code> to special value <code>-1</code>. In this mode, the output consists of <code>indentation</code>, followed by a pretty-printed hex dump of every byte in <code>data</code> (no matter how many), followed by a pretty-printed ASCII-printable (or '.' if not so printable) character for each byte; that's it. No newline is added, and <code>indentation</code> is included only the one time. It is recommended to therefore print "in-line" inside log messages (etc.) without surrounding newlines, etc., when using this mode.</li>
<li>Multi-line mode is chosen by setting <code>bytes_per_line</code> to a positive value; or 0 which auto-selects a decent default positive value. Then, each line represents up to that many bytes, which are pretty-printed similarly to single-line mode, in order of appearance in <code>data</code> (with the last such line representing the last few bytes, formatting nicely including accounting for potentially fewer than the desired # of bytes per line). Every line starts with <code>indentation</code> and ends with a newline &ndash; including the last line. Therefore, it is recommended to precede this call with an output of a newline and to avoid doing so after that call (unless blank line is desired).</li>
</ul>
<p >Example with a single contiguous memory area, multi-line mode:</p>
<div class="fragment"><div class="line">array&lt;uint8_t, 256 * 256&gt; bytes(...);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Output to cout.</span></div>
<div class="line">cout</div>
<div class="line">  &lt;&lt; <span class="stringliteral">&quot;Buffer contents: [\n&quot;</span>;</div>
<div class="line"><a class="code hl_function" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf">buffers_to_ostream</a>(cout,</div>
<div class="line">                   boost::asio::buffer(bytes), <span class="comment">// Turn a single memory array into a buffer sequence.</span></div>
<div class="line">                   <span class="stringliteral">&quot;  &quot;</span>);</div>
<div class="line">  &lt;&lt; <span class="stringliteral">&quot;].&quot;</span>; <span class="comment">// This will be on its own line at the end.</span></div>
<div class="ttc" id="anamespaceflow_1_1util_html_aa132928b364caefca5c3821e019924bf"><div class="ttname"><a href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf">flow::util::buffers_to_ostream</a></div><div class="ttdeci">std::ostream &amp; buffers_to_ostream(std::ostream &amp;os, const Const_buffer_sequence &amp;data, const std::string &amp;indentation, size_t bytes_per_line)</div><div class="ttdoc">Writes a multi- or single-line string representation of the provided binary data to an output stream,...</div><div class="ttdef"><b>Definition:</b> util.hpp:413</div></div>
</div><!-- fragment --><p >See also <a class="el" href="namespaceflow_1_1util.html#a16357344c21456b86b7de3085e2661a2" title="Identical to buffers_to_ostream() but returns an std::string instead of writing to a given ostream.">buffers_dump_string()</a> which returns a string and can thus be more easily used directly inside <a class="el" href="log_8hpp.html#a07561c1c3f16b6c2c7335a09e25298c9" title="Logs a DATA message into flow::log::Logger *get_logger() with flow::log::Component get_log_component(...">FLOW_LOG_DATA()</a> and similar log macros.</p>
<h3>Performance</h3>
<p >This thing is slow... it's not trying to be fast and can't be all that fast anyway. As usual, though, if used in <a class="el" href="log_8hpp.html#a07561c1c3f16b6c2c7335a09e25298c9" title="Logs a DATA message into flow::log::Logger *get_logger() with flow::log::Component get_log_component(...">FLOW_LOG_DATA()</a> (etc.) its slowness will only come into play if the log filter passes which (esp. for log::Severity::S_DATA) it usually won't.</p>
<p >That said <a class="el" href="namespaceflow_1_1util.html#a16357344c21456b86b7de3085e2661a2" title="Identical to buffers_to_ostream() but returns an std::string instead of writing to a given ostream.">buffers_dump_string()</a> is even slower, because it'll use an intermediate <code>ostream</code> independent of whatever <code>ostream</code> you may or may not be placing the resulting string. However it's easier to use with <code>FLOW_LOG_...()</code>, and since in that case perf is typically not an issue, it makes sense to use the easier thing typically.</p>
<p >However, if you do want to avoid that extra copy and need to <em>also</em> use <a class="el" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf" title="Writes a multi- or single-line string representation of the provided binary data to an output stream,...">buffers_to_ostream()</a> directly inside <code>FLOW_LOG_...()</code> then the following technique isn't too wordy and works:</p>
<div class="fragment"><div class="line"><span class="keyword">const</span> array&lt;uint8_t, 256 * 256&gt; bytes(...);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Log with a flow::log macro.</span></div>
<div class="line"><span class="keyword">const</span> flow::Function&lt;ostream&amp; (ostream&amp;)&gt; os_manip = [&amp;](ostream&amp; os) -&gt; ostream&amp;</div>
<div class="line">{</div>
<div class="line">  <span class="keywordflow">return</span> <a class="code hl_function" href="namespaceflow_1_1util.html#aa132928b364caefca5c3821e019924bf">buffers_to_ostream</a>(os, boost::asio::buffer(bytes), <span class="stringliteral">&quot;  &quot;</span>);</div>
<div class="line">};</div>
<div class="line"><a class="code hl_define" href="log_8hpp.html#a325fdd4b5cf0be49b37d3b7b7c29070d">FLOW_LOG_INFO</a>(<span class="stringliteral">&quot;Buffer contents: [\n&quot;</span> &lt;&lt; os_manip &lt;&lt; <span class="stringliteral">&quot;].&quot;</span>);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Above is probably more performant than:</span></div>
<div class="line"><a class="code hl_define" href="log_8hpp.html#a325fdd4b5cf0be49b37d3b7b7c29070d">FLOW_LOG_INFO</a>(<span class="stringliteral">&quot;Buffer contents: [\n&quot;</span></div>
<div class="line">              &lt;&lt; <a class="code hl_function" href="namespaceflow_1_1util.html#a16357344c21456b86b7de3085e2661a2">buffers_dump_string</a>(boost::asio::buffer(bytes), <span class="stringliteral">&quot;  &quot;</span>) <span class="comment">// Intermediate+copy, slow....</span></div>
<div class="line">              &lt;&lt; <span class="stringliteral">&quot;].&quot;</span>);</div>
<div class="line"><span class="comment">// flow::util::ostream_op_string() is a bit of an improvement but still. :-)</span></div>
<div class="ttc" id="alog_8hpp_html_a325fdd4b5cf0be49b37d3b7b7c29070d"><div class="ttname"><a href="log_8hpp.html#a325fdd4b5cf0be49b37d3b7b7c29070d">FLOW_LOG_INFO</a></div><div class="ttdeci">#define FLOW_LOG_INFO(ARG_stream_fragment)</div><div class="ttdoc">Logs an INFO message into flow::log::Logger *get_logger() with flow::log::Component get_log_component...</div><div class="ttdef"><b>Definition:</b> log.hpp:197</div></div>
<div class="ttc" id="anamespaceflow_1_1util_html_a16357344c21456b86b7de3085e2661a2"><div class="ttname"><a href="namespaceflow_1_1util.html#a16357344c21456b86b7de3085e2661a2">flow::util::buffers_dump_string</a></div><div class="ttdeci">std::string buffers_dump_string(const Const_buffer_sequence &amp;data, const std::string &amp;indentation, size_t bytes_per_line)</div><div class="ttdoc">Identical to buffers_to_ostream() but returns an std::string instead of writing to a given ostream.</div><div class="ttdef"><b>Definition:</b> util.hpp:506</div></div>
</div><!-- fragment --><h3>Rationale</h3>
<p >The reason it returns <code>os</code> and takes a reference-to-mutable instead of the customary (for this project's style, to indicate modification potential at call sites) pointer-to-mutable is in order to be <code>bind()</code>able in such a way as to make an <code>ostream</code> manipulator. In the example above we use a lambda instead of <code>bind()</code> however.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Const_buffer_sequence</td><td>Type that models the boost.asio <code>ConstBufferSequence</code> concept (see Boost docs) which represents 1 or more scattered buffers in memory (only 1 buffer in a sequence is common). In particular <code>boost::asio::const_buffer</code> works when dumping a single buffer. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>The output stream to which to write. </td></tr>
    <tr><td class="paramname">data</td><td>The data to write, given as an immutable sequence of buffers each of which is essentially a pointer and length. (Reminder: it is trivial to make such an object from a single buffer as well; for example given <code>array&lt;uint8_t, 256&gt; data</code> (an array of 256 bytes), you can just pass <code>boost::asio::buffer(data)</code>, as the latter returns an object whose type satisfies requirements of <code>Const_buffer_sequence</code> despite the original memory area being nothing more than a single byte array.) </td></tr>
    <tr><td class="paramname">indentation</td><td>The indentation to use at the start of every line of output. </td></tr>
    <tr><td class="paramname">bytes_per_line</td><td>If 0, act as-if a certain default positive value were passed; and then: If <code>-1</code>, single-line mode is invoked. If a positive value, multi-line mode is invoked, with all lines but the last one consisting of a dump of that many contiguous bytes of <code>data</code>. (Yes, multi-line mode is still in force, even if there are only enough bytes in <code>data</code> for one line of output anyway.) </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>os</code>. </dd></dl>

</div>
</div>
<a id="a6b7316b3ed6d89f54c91e17c2aab101e" name="a6b7316b3ed6d89f54c91e17c2aab101e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6b7316b3ed6d89f54c91e17c2aab101e">&#9670;&nbsp;</a></span>ceil_div()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Integer &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">Integer flow::util::ceil_div </td>
          <td>(</td>
          <td class="paramtype">Integer&#160;</td>
          <td class="paramname"><em>dividend</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Integer&#160;</td>
          <td class="paramname"><em>divisor</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns the result of the given non-negative integer divided by a positive integer, rounded up to the nearest integer. </p>
<p >Internally, it avoids floating-point math for performance.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Integer</td><td>A signed or unsigned integral type. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">dividend</td><td>Dividend; non-negative or assertion trips. </td></tr>
    <tr><td class="paramname">divisor</td><td>Divisor; positive or assertion trips. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Ceiling of <code>(dividend / divisor)</code>. </dd></dl>

</div>
</div>
<a id="a418b56a178c07100eef78da5c9d6ee7a" name="a418b56a178c07100eef78da5c9d6ee7a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a418b56a178c07100eef78da5c9d6ee7a">&#9670;&nbsp;</a></span>deep_size()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">size_t flow::util::deep_size </td>
          <td>(</td>
          <td class="paramtype">const std::string &amp;&#160;</td>
          <td class="paramname"><em>val</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Estimate of memory footprint of the given value, including memory allocated on its behalf &ndash; but excluding its shallow <code>sizeof</code>! &ndash; in bytes. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">val</td><td>Value. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="a3ce0e3794a3a84dd26b4aa7b013f6276" name="a3ce0e3794a3a84dd26b4aa7b013f6276"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3ce0e3794a3a84dd26b4aa7b013f6276">&#9670;&nbsp;</a></span>feed_args_to_ostream() <span class="overload">[1/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename T &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void flow::util::feed_args_to_ostream </td>
          <td>(</td>
          <td class="paramtype">std::ostream *&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>only_ostream_arg</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>"Induction base" for a variadic function template, this simply outputs given item to given <code>ostream</code> via <code>&lt;&lt;</code>. </p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">T</td><td>See each of <code>...T</code> in <a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484" title="Writes to the specified string, as if the given arguments were each passed, via &lt;&lt; in sequence,...">ostream_op_to_string()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Pointer to stream to which to sequentially send arguments for output. </td></tr>
    <tr><td class="paramname">only_ostream_arg</td><td>See each of <code>ostream_args</code> in <a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484" title="Writes to the specified string, as if the given arguments were each passed, via &lt;&lt; in sequence,...">ostream_op_to_string()</a>. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="af92e6183c2071f4166d4b5a91f50d70c" name="af92e6183c2071f4166d4b5a91f50d70c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af92e6183c2071f4166d4b5a91f50d70c">&#9670;&nbsp;</a></span>feed_args_to_ostream() <span class="overload">[2/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename T1 , typename ... T_rest&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void flow::util::feed_args_to_ostream </td>
          <td>(</td>
          <td class="paramtype">std::ostream *&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T1 const &amp;&#160;</td>
          <td class="paramname"><em>ostream_arg1</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T_rest const &amp;...&#160;</td>
          <td class="paramname"><em>remaining_ostream_args</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>"Induction step" version of variadic function template that simply outputs arguments 2+ via <code>&lt;&lt;</code> to the given <code>ostream</code>, in the order given. </p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">...T_rest</td><td>See <code>...T</code> in <a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484" title="Writes to the specified string, as if the given arguments were each passed, via &lt;&lt; in sequence,...">ostream_op_to_string()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">remaining_ostream_args</td><td>See <code>ostream_args</code> in <a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484" title="Writes to the specified string, as if the given arguments were each passed, via &lt;&lt; in sequence,...">ostream_op_to_string()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">T1</td><td>Same as each of <code>...T_rest</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">ostream_arg1</td><td>Same as each of <code>remaining_ostream_args</code>. </td></tr>
    <tr><td class="paramname">os</td><td>Pointer to stream to which to sequentially send arguments for output. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a024ddda9acb2b66f2a1b35cdb0c016aa" name="a024ddda9acb2b66f2a1b35cdb0c016aa"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a024ddda9acb2b66f2a1b35cdb0c016aa">&#9670;&nbsp;</a></span>in_closed_open_range()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename T &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::in_closed_open_range </td>
          <td>(</td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>min_val</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>val</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>max_val</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns <code>true</code> if and only if the given value is within the given range, given as a [low, high) pair. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">min_val</td><td>Lower part of the range. </td></tr>
    <tr><td class="paramname">val</td><td>Value to check. </td></tr>
    <tr><td class="paramname">max_val</td><td>Higher part of the range. Must be greater than <code>min_val</code>, or behavior is undefined. </td></tr>
  </table>
  </dd>
</dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">T</td><td>A type for which the operation <code>x &lt; y</code> is defined and makes sense. Examples: <code>double</code>, <code>char</code>, <code>unsigned int</code>, <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">Fine_duration</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if and only if <code>val</code> is in [<code>min_val</code>, <code>max_val</code>), i.e., <code>min_val</code> &lt;= <code>val</code> &lt; <code>max_val</code>. </dd></dl>

</div>
</div>
<a id="ab10bc9e8bef148f875aa743fe0852743" name="ab10bc9e8bef148f875aa743fe0852743"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab10bc9e8bef148f875aa743fe0852743">&#9670;&nbsp;</a></span>in_closed_range()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename T &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::in_closed_range </td>
          <td>(</td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>min_val</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>val</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>max_val</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns <code>true</code> if and only if the given value is within the given range, inclusive. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">min_val</td><td>Lower part of the range. </td></tr>
    <tr><td class="paramname">val</td><td>Value to check. </td></tr>
    <tr><td class="paramname">max_val</td><td>Higher part of the range. Must be greater than or equal to <code>min_val</code>, or behavior is undefined. </td></tr>
  </table>
  </dd>
</dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">T</td><td>A type for which the operation <code>x &lt; y</code> is defined and makes sense. Examples: <code>double</code>, <code>char</code>, <code>unsigned int</code>, <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">Fine_duration</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if and only if <code>val</code> is in [<code>min_val</code>, <code>max_val</code>]. </dd></dl>

</div>
</div>
<a id="a8ae762ea4f743a98a73953d7f9ec2164" name="a8ae762ea4f743a98a73953d7f9ec2164"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8ae762ea4f743a98a73953d7f9ec2164">&#9670;&nbsp;</a></span>in_open_closed_range()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename T &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::in_open_closed_range </td>
          <td>(</td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>min_val</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>val</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>max_val</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns <code>true</code> if and only if the given value is within the given range, given as a (low, high] pair. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">min_val</td><td>Lower part of the range. </td></tr>
    <tr><td class="paramname">val</td><td>Value to check. </td></tr>
    <tr><td class="paramname">max_val</td><td>Higher part of the range. Must be greater than <code>min_val</code>, or behavior is undefined. </td></tr>
  </table>
  </dd>
</dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">T</td><td>A type for which the operation <code>x &lt; y</code> is defined and makes sense. Examples: <code>double</code>, <code>char</code>, <code>unsigned int</code>, <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">Fine_duration</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if and only if <code>val</code> is in (<code>min_val</code>, <code>max_val</code>], i.e., <code>min_val</code> &lt; <code>val</code> &lt;= <code>max_val</code>. </dd></dl>

</div>
</div>
<a id="a733448fee07c2a77e343a3f1590ff82e" name="a733448fee07c2a77e343a3f1590ff82e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a733448fee07c2a77e343a3f1590ff82e">&#9670;&nbsp;</a></span>in_open_open_range()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename T &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::in_open_open_range </td>
          <td>(</td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>min_val</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>val</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;&#160;</td>
          <td class="paramname"><em>max_val</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns <code>true</code> if and only if the given value is within the given range, given as a (low, high) pair. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">min_val</td><td>Lower part of the range. </td></tr>
    <tr><td class="paramname">val</td><td>Value to check. </td></tr>
    <tr><td class="paramname">max_val</td><td>Higher part of the range. Must be at least 2 greater than <code>min_val</code>, or behavior is undefined. </td></tr>
  </table>
  </dd>
</dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">T</td><td>A type for which the operation <code>x &lt; y</code> is defined and makes sense. Examples: <code>double</code>, <code>char</code>, <code>unsigned int</code>, <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">Fine_duration</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if and only if <code>val</code> is in (<code>min_val</code>, <code>max_val</code>), i.e., <code>min_val</code> &lt; <code>val</code> &lt; <code>max_val</code>. </dd></dl>

</div>
</div>
<a id="a18a29d6a6e65c3b96c52b5cad5971266" name="a18a29d6a6e65c3b96c52b5cad5971266"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a18a29d6a6e65c3b96c52b5cad5971266">&#9670;&nbsp;</a></span>istream_to_enum()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Enum &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">Enum flow::util::istream_to_enum </td>
          <td>(</td>
          <td class="paramtype">std::istream *&#160;</td>
          <td class="paramname"><em>is_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Enum&#160;</td>
          <td class="paramname"><em>enum_default</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Enum&#160;</td>
          <td class="paramname"><em>enum_sentinel</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">bool&#160;</td>
          <td class="paramname"><em>accept_num_encoding</em> = <code>true</code>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">bool&#160;</td>
          <td class="paramname"><em>case_sensitive</em> = <code>false</code>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Enum&#160;</td>
          <td class="paramname"><em>enum_lowest</em> = <code>Enum(0)</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Deserializes an <code>enum class</code> value from a standard input stream. </p>
<p >Reads up to but not including the next non-alphanumeric-or-underscore character; the resulting string is then mapped to an <code>Enum</code>. If none is recognized, <code>enum_default</code> is the result. The recognized values are:</p><ul>
<li>"0", "1", ...: Corresponds to the underlying-integer conversion to that <code>Enum</code>. (Can be disabled optionally.)</li>
<li>Case-[in]sensitive string encoding of the <code>Enum</code>, as determined by <code>operator&lt;&lt;(ostream&amp;)</code> &ndash; which must exist (or this will not compile). Informally we recommend the encoding to be the non-S_-prefix part of the actual <code>Enum</code> member; e.g., <code>"WARNING"</code> for <a class="el" href="namespaceflow_1_1log.html#a5c602384e6fe9d7642740ac2fae4ad04a4aee6034ce9dbc2b5c36f27c80abe021" title="Message indicates a &quot;bad&quot; condition that is not frequent enough to be of severity Sev::S_TRACE.">log::Sev::S_WARNING</a>. If the scanned token does not map to any of these, or if end-of-input is encountered immediately (empty token), then <code>enum_default</code> is returned.</li>
</ul>
<p >Error semantics: There are no invalid values or exceptions thrown; <code>enum_default</code> returned is the worst case. Do note <code>*is_ptr</code> may not be <code>good() == true</code> after return.</p>
<p >Tip: It is convenient to implement <code>operator&gt;&gt;(istream&amp;)</code> in terms of <a class="el" href="namespaceflow_1_1util.html#a18a29d6a6e65c3b96c52b5cad5971266" title="Deserializes an enum class value from a standard input stream.">istream_to_enum()</a>. With both <code>&gt;&gt;</code> and <code>&lt;&lt;</code> available, serialization/deserialization of the <code>enum class</code> will work; this enables a few key things to work, including parsing from config file/command line via and conversion from <code>string</code> via <code>lexical_cast</code>.</p>
<p >Informal convention suggestion: <code>S_END_SENTINEL</code> should be the sentinel member of <code>Enum</code>. E.g., see <a class="el" href="namespaceflow_1_1log.html#a5c602384e6fe9d7642740ac2fae4ad04" title="Enumeration containing one of several message severity levels, ordered from highest to lowest.">log::Sev</a>.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Enum</td><td>An <code>enum class</code> which must satisfy the following requirements or else risk undefined behavior (if it compiles): An element, <code>enum_lowest</code>, has a non-negative integer value. Subsequent elements are strictly monotonically increasing with increment 1, up to and including <code>enum_sentinel</code>. (Elements outside [<code>enum_lowest</code>, <code>enum_sentinel</code>] may exist, as long as their numeric values don't conflict with those in-range, but informally we recommend against this.) <code>ostream &lt;&lt; Enum</code> exists and works without throwing for all values in range [<code>enum_lowest</code>, <code>enum_sentinel</code>). Each <code>&lt;&lt;</code>-serialized string must be distinct from the others. Each <code>&lt;&lt;</code>-serialized string must start with a non-digit and must consist only of alphanumerics and underscores. Exception: digit-leading is allowed if and only if <code>!accept_num_encoding</code>, though informally we recommend against it as a convention.</td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">is_ptr</td><td>Stream from which to deserialize. </td></tr>
    <tr><td class="paramname">enum_default</td><td>Value to return if the token does not match either the numeric encoding (if enabled) or the <code>&lt;&lt;</code> encoding. <code>enum_sentinel</code> is a sensible (but not the only sensible) choice. </td></tr>
    <tr><td class="paramname">enum_sentinel</td><td><code>Enum</code> value such that all valid deserializable values have numeric conversions strictly lower than it. </td></tr>
    <tr><td class="paramname">accept_num_encoding</td><td>If <code>true</code>, a numeric value is accepted as an encoding; otherwise it is not (and will yield <code>enum_default</code> like any other non-matching token). </td></tr>
    <tr><td class="paramname">case_sensitive</td><td>If <code>true</code>, then the token must exactly equal an <code>ostream&lt;&lt;</code> encoding of a non-sentinel <code>Enum</code>; otherwise it may equal it modulo different case. </td></tr>
    <tr><td class="paramname">enum_lowest</td><td>The lowest <code>Enum</code> value. Its integer value is very often 0, sometimes 1. Behavior undefined if it is negative. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="a03984e29450abf9cf287c501d6c8f866" name="a03984e29450abf9cf287c501d6c8f866"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a03984e29450abf9cf287c501d6c8f866">&#9670;&nbsp;</a></span>key_exists()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Container &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::key_exists </td>
          <td>(</td>
          <td class="paramtype">const Container &amp;&#160;</td>
          <td class="paramname"><em>container</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const typename Container::key_type &amp;&#160;</td>
          <td class="paramname"><em>key</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns <code>true</code> if and only if the given key is present at least once in the given associative container. </p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Container</td><td>Associative container type (<code>boost::unordered_map</code>, <code>std::set</code>, etc.). In particular must have the members <code>find()</code>, <code>end()</code>, and <code>key_type</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">container</td><td>Container to search. </td></tr>
    <tr><td class="paramname">key</td><td>Key to find. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="a685b86585da2fa5186f51854e7ae1561" name="a685b86585da2fa5186f51854e7ae1561"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a685b86585da2fa5186f51854e7ae1561">&#9670;&nbsp;</a></span>ostream_op_string()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename ... T&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">std::string flow::util::ostream_op_string </td>
          <td>(</td>
          <td class="paramtype">T const &amp;...&#160;</td>
          <td class="paramname"><em>ostream_args</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Equivalent to <a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484" title="Writes to the specified string, as if the given arguments were each passed, via &lt;&lt; in sequence,...">ostream_op_to_string()</a> but returns a new <code>string</code> by value instead of writing to the caller's <code>string</code>. </p>
<p >This is useful at least in constructor initializers, where it is not possible to first declare a stack variable.</p>
<p >With the C++11-y use of move semantics in STL it should be no slower than using <code><a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484" title="Writes to the specified string, as if the given arguments were each passed, via &lt;&lt; in sequence,...">ostream_op_to_string()</a></code> &ndash; meaning, it is no slower, period, as this library now requires C++11.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">...T</td><td>See <a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484" title="Writes to the specified string, as if the given arguments were each passed, via &lt;&lt; in sequence,...">ostream_op_to_string()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">ostream_args</td><td>See <a class="el" href="namespaceflow_1_1util.html#a8afd30c50bcd670d45442df49d1da484" title="Writes to the specified string, as if the given arguments were each passed, via &lt;&lt; in sequence,...">ostream_op_to_string()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Resulting <code>std::string</code>. </dd></dl>

</div>
</div>
<a id="a8afd30c50bcd670d45442df49d1da484" name="a8afd30c50bcd670d45442df49d1da484"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8afd30c50bcd670d45442df49d1da484">&#9670;&nbsp;</a></span>ostream_op_to_string()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename ... T&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void flow::util::ostream_op_to_string </td>
          <td>(</td>
          <td class="paramtype">std::string *&#160;</td>
          <td class="paramname"><em>target_str</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">T const &amp;...&#160;</td>
          <td class="paramname"><em>ostream_args</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Writes to the specified string, as if the given arguments were each passed, via <code>&lt;&lt;</code> in sequence, to an <code>ostringstream</code>, and then the result were appended to the aforementioned string variable. </p>
<p >Tip: It works nicely, 99% as nicely as simply <code>&lt;&lt;</code>ing an <code>ostream</code>; but certain language subtleties mean you may have to fully qualify some template instances among <code>ostream_args</code>. Do so if you receive a "deduced incomplete pack" (clang) or similar error, as I have seen when using, e.g., <code>chrono::symbol_format</code> formatter (which the compile error forced me to qualify as: <code>symbol_format&lt;char, ostream::traits_type&gt;</code>).</p>
<dl class="section see"><dt>See also</dt><dd>log::Thread_local_string_appender for an even more efficient version of this for some applications that can also enable a continuous stream across multiple stream-writing statements over time.</dd></dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">...T</td><td>Each type <code>T</code> is such that <code>os &lt;&lt; t</code>, with types <code>T const &amp; t</code> and <code>ostream&amp; os</code>, builds and writes <code>t</code> to <code>os</code>, returning lvalue <code>os</code>. Usually in practice this means the existence of <code>ostream&amp; operator&lt;&lt;(ostream&amp;, T const &amp;)</code> or <code>ostream&amp; operator&lt;&lt;(ostream&amp;, T)</code> overload, the latter usually for basic types <code>T</code>. See also tip above, if compiler is unable to deduce a given <code>T</code> (even when it <em>would</em> deduce it in <code>os &lt;&lt; t</code>). </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">target_str</td><td>Pointer to the string to which to append. </td></tr>
    <tr><td class="paramname">ostream_args</td><td>One or more arguments, such that each argument <code>arg</code> is suitable for <code>os &lt;&lt; arg</code>, where <code>os</code> is an <code>ostream</code>. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="aad8c8f7335eb892350dc386cb4be397e" name="aad8c8f7335eb892350dc386cb4be397e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aad8c8f7335eb892350dc386cb4be397e">&#9670;&nbsp;</a></span>schedule_task_at()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Scheduled_task_handler &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">Scheduled_task_handle</a> flow::util::schedule_task_at </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8">Fine_time_pt</a> &amp;&#160;</td>
          <td class="paramname"><em>at</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">bool&#160;</td>
          <td class="paramname"><em>single_threaded</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">Task_engine</a> *&#160;</td>
          <td class="paramname"><em>task_engine</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Scheduled_task_handler &amp;&amp;&#160;</td>
          <td class="paramname"><em>task_body_moved</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Identical to <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> except the time is specified in absolute terms. </p>
<h3>Performance note</h3>
<p >The current implementation is such that there is no performance benefit to using <code>schedule_task_from_now(at - Fine_clock::now(), ...)</code> over <code>schedule_task_at(at, ...)</code>. Therefore, if it is convenient for caller's code reuse to do the former, there is no perf downside to it, so feel free.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>See <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a>. </td></tr>
    <tr><td class="paramname">at</td><td>Fire at this absolute time. If this is in the past, it will fire ASAP. </td></tr>
    <tr><td class="paramname">single_threaded</td><td>See <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a>. </td></tr>
    <tr><td class="paramname">task_engine</td><td>See <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a>. </td></tr>
    <tr><td class="paramname">task_body_moved</td><td>See <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a>.</dd></dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Scheduled_task_handler</td><td>See <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a>. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a74d4a66fb00055be4e1bd6ee98e04667" name="a74d4a66fb00055be4e1bd6ee98e04667"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a74d4a66fb00055be4e1bd6ee98e04667">&#9670;&nbsp;</a></span>schedule_task_from_now()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Scheduled_task_handler &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">Scheduled_task_handle</a> flow::util::schedule_task_from_now </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79">Fine_duration</a> &amp;&#160;</td>
          <td class="paramname"><em>from_now</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">bool&#160;</td>
          <td class="paramname"><em>single_threaded</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">Task_engine</a> *&#160;</td>
          <td class="paramname"><em>task_engine</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Scheduled_task_handler &amp;&amp;&#160;</td>
          <td class="paramname"><em>task_body_moved</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Schedule the given function to execute in a certain amount of time: A handy wrapper around <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> (asio's timer facility). </p>
<p >Compared to using <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>, this has far simplified semantics at the cost of certain less-used features of <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>. Recommend using this facility when sufficient; otherwise use <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> directly. The trade-offs are explained below, but first:</p>
<h3>Semantics</h3>
<p >Conceptually this is similar to JavaScript's ubiquitous (albeit single-threaded) <code>setTimeout()</code> feature. The given function shall execute as if <code>post()</code>ed onto the given <code>Task_engine</code>; unless successfully canceled by <code>scheduled_task_cancel(X)</code>, where X is the (optionally used and entirely ignorable) returned handle. Barring unrelated crashes/etc. there are exactly three mutually exclusive outcomes of this function executing:</p><ul>
<li>It runs at the scheduled time, with the <code>bool short_fire</code> arg to it set to <code>false</code>.</li>
<li>It runs before the scheduled time, with <code>short_fire == true</code>. To trigger this, use <a class="el" href="namespaceflow_1_1util.html#abe8d04de7ba9ac770112ee585b77cd20" title="Attempts to reschedule a previously scheduled (by schedule_task_from_now() or similar) task to fire i...">scheduled_task_short_fire()</a> before the scheduled time.<ul>
<li>If this loses the race with normal firing, the short-fire function will indicate that via its return value.</li>
</ul>
</li>
<li>It never runs. To trigger this, use <a class="el" href="namespaceflow_1_1util.html#ad92e68a1b22556f2625292098c0036a2" title="Attempts to prevent the execution of a previously scheduled (by schedule_task_from_now() or similar) ...">scheduled_task_cancel()</a> before the scheduled time.<ul>
<li>If this loses the race with normal firing, the cancel function will indicate that via its return value.</li>
</ul>
</li>
</ul>
<p >All related functions are thread-safe w/r/t a given returned <code>Scheduled_task_handle</code>, if <code>single_threaded == false</code>. In addition, for extra performance (internally, by omitting certain locking), set <code>single_threaded = true</code> only if you can guarantee the following:</p><ul>
<li><code>*task_engine</code> is <code>run()</code>ning in no more than one thread throughout all work with the returned <code>Scheduled_task_handle</code> including the present function.</li>
<li>Any calls w/r/t the returned <code>Scheduled_task_handle</code> are also &ndash; if at all &ndash; called from that one thread.</li>
</ul>
<p >The minimum is step 1: Call <a class="el" href="namespaceflow_1_1util.html#aad8c8f7335eb892350dc386cb4be397e" title="Identical to schedule_task_from_now() except the time is specified in absolute terms.">schedule_task_at()</a> or <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a>. Optionally, if one saves the return value X from either, one can do step 2: <code>scheduled_task_short_fire(X)</code> or <code>scheduled_task_cancel(X)</code>, which will succeed (return <code>true</code>) if called sufficiently early. There is no step 3; any subsequent calls on X will fail (return <code>false</code>).</p>
<h3>Simplifications over <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a></h3>
<ul>
<li>There is no need to, separately, create a <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> object; set the firing time; and kick off the asynchronous wait. One call does everything, and there is no object to maintain. Sole exception to the latter: <em>if</em> you want to be able to cancel or short-circuit the task later on, you can optionally save the return value and later call a <code>scheduled_task_*()</code> function on it.)</li>
<li>You need not worry about internal errors &ndash; no need to worry about any <code>Error_code</code> passed in to your task function.</li>
<li>Cancellation semantics are straightforward and intuitive, lacking corner cases of vanilla <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>. To wit:<ul>
<li>A successful <a class="el" href="namespaceflow_1_1util.html#ad92e68a1b22556f2625292098c0036a2" title="Attempts to prevent the execution of a previously scheduled (by schedule_task_from_now() or similar) ...">scheduled_task_cancel()</a> call means the task will <em>not</em> execute. (<code>Timer::cancel()</code> means it will still execute but with <code>operation_aborted</code> code.)</li>
<li><code>Timer::cancel()</code> can result in ~3 behaviors: it already executed, so it does nothing; it has not yet executed but was JUST about to execute, so it will still execute with non-<code>operation_aborted</code> code; it has not yet executed, so now it will execute but with <code>operation_aborted</code>. With this facility, it's simpler: it either succeeds (so acts per previous bullet &ndash; does not execute); or it fails, hence it will have executed (and there is no <code>Error_code</code> to decipher).</li>
</ul>
</li>
<li>Short-firing semantics are arguably more intuitive. With <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>, <code>cancel()</code> actually means short-firing (firing ASAP) but with a special <code>Error_code</code>. One can also change the expiration time to the past to short-fire in a different way. With this facility, cancellation means it won't run; and <a class="el" href="namespaceflow_1_1util.html#abe8d04de7ba9ac770112ee585b77cd20" title="Attempts to reschedule a previously scheduled (by schedule_task_from_now() or similar) task to fire i...">scheduled_task_short_fire()</a> means it will fire early; that's it.</li>
</ul>
<h3>Features lost vs. <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a></h3>
<ul>
<li>A <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> can be reused repeatedly. This <em>might</em> be more performant than using this facility repeatedly, since (internally) that approach creates a <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> each time. Note: We have no data about the cost of initializing a new <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>, other than the fact I peeked at the boost.asio source and saw that the construction of a <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> isn't obviously trivial/cheap &ndash; which does NOT mean it isn't just cheap in reality, only that that's not immediately clear.<ul>
<li>A rule of thumb in answering the question, 'Is this facility fine to just call repeatedly, or should we reuse a <code>Timer</code> for performance?': It <em>might</em> not be fine if and only if timer firings and/or cancellations occur many times a second in a performance-sensitive environment. E.g., if it's something fired and/or canceled every second repeatedly, it's fine; it it's packet pacing that must sensitively fire near the resolution limit of the native <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> facility, it <em>might</em> not be fine, and it's safer to use <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> repeatedly.</li>
</ul>
</li>
<li>A <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> can be re-scheduled to fire at an arbitrary different time than originally set. We provide no such facility. (We could provide such an API at the cost of API and implementation complexity; it's a judgment call, but I feel at that point just use a <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>.)<ul>
<li>However, we provide one special case of this: the timer can be fired ASAP, a/k/a short-fired, via <a class="el" href="namespaceflow_1_1util.html#abe8d04de7ba9ac770112ee585b77cd20" title="Attempts to reschedule a previously scheduled (by schedule_task_from_now() or similar) task to fire i...">scheduled_task_short_fire()</a>.</li>
</ul>
</li>
<li>One can (incrementally) schedule 2+ tasks to fire at the scheduled time on one <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>; this facility only takes exactly 1 task, up-front. (We could provide such an API, but again this feels like it defeats the point.)</li>
<li><p class="startli"><a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> has certain informational accessors (like one that returns the scheduled firing time) that we lack. (Again, we could provide this also &ndash; but why?)</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000067">Todo:</a></b></dt><dd>We could eliminate <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> potential limitation versus <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> wherein each call constructs (internally) a new <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>. A pool of <code>Timer</code>s can be internally maintained to implement this. This may or may not be worth the complexity, but if the API can remain identically simple while cleanly eliminating the one perf-related reason to choose <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> over this simpler facility, then that is a clean win from the API user's point of view. By comparison, other possible improvements mentioned <em>complicate</em> the API which makes them less attractive.</dd></dl>
</li>
</ul>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">util::Timer</a> doc header for native <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> resolution limitations (which apply to quite-low <code>from_now</code> values). </dd></dl>
<dl class="section note"><dt>Note</dt><dd>Design note: This is a small, somewhat C-style set of functions &ndash; C-style in that it returns a handle on which to potentially call more functions as opposed to just being a class with methods. This is intentional, because <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> already provides the stateful <code>class</code>. The picture is slightly muddled because we DO provide some "methods" &ndash; so why not make it a <code>class</code> after all, just a simpler one than <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>? Answer: I believe this keeps the API simple: Step 1: Schedule it. Step 2 (optional): Short-fire or cancel it. There are no corner cases introduced as might have been via increased potential statefulness inherent with a class. But see the following to-do.</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000068">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> and surrounding API provides an easy way to schedule a thing into the future, but it is built on top of boost.asio <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">util::Timer</a> directly; an intermediate wrapper class around this would be quite useful in its own right so that all boost.asio features including its perf-friendliness would be retained along with eliminating its annoyances (around canceling-but-not-really and similar). Then scheduled_task_from_now() would be internally even simpler, while a non-annoying <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">util::Timer</a> would become available for more advanced use cases. echan may have such a class (in a different project) ready to adapt (called <code>Serial_task_timer</code>). I believe it internally uses integer "task ID" to distinguish between scheduled tasks issued in some chronological order, so that boost.asio firing a task after it has been canceled/pre-fired can be easily detected.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logging, if any &ndash; including in the background &ndash; will be done via this logger. </td></tr>
    <tr><td class="paramname">from_now</td><td>Fire ASAP once this time period passes (0 to fire ASAP). A negative value has the same effect as 0. </td></tr>
    <tr><td class="paramname">single_threaded</td><td>Set to a true value if and only if, basically, <code>*task_engine</code> is single-threaded, and you promise not to call anything on the returned <code>Scheduled_task_handle</code> except from that same thread. More formally, see above. </td></tr>
    <tr><td class="paramname">task_engine</td><td>The <code>Task_engine</code> onto which the given task may be <code>post()</code>ed (or equivalent). </td></tr>
    <tr><td class="paramname">task_body_moved</td><td>The task to execute within <code>*task_engine</code> unless successfully canceled. See template param doc below also regarding <code>Strand</code> and other executor binding. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Handle to the scheduled task which can be ignored in most cases. If you want to cancel, short-fire, etc. subsequently, save this (by value) and operate on it subsequently, e.g., with <a class="el" href="namespaceflow_1_1util.html#ad92e68a1b22556f2625292098c0036a2" title="Attempts to prevent the execution of a previously scheduled (by schedule_task_from_now() or similar) ...">scheduled_task_cancel()</a>.</dd></dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Scheduled_task_handler</td><td>Completion handler with signature compatible with <code>void (bool short_fired)</code>. This allows for standard boost.asio semantics, including associating with an executor such as a <code>boost::asio::io_context::strand</code>. In particular you may pass in: <code>bind_executor(S, F)</code>, where <code>F(bool short_fire)</code> is the handler, and <code>S</code> is a <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">Strand</a> (or other executor). Binding to a <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">Strand</a> will ensure the fired or short-fired body will not execute concurrently with any other handler also bound to it. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="ad92e68a1b22556f2625292098c0036a2" name="ad92e68a1b22556f2625292098c0036a2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad92e68a1b22556f2625292098c0036a2">&#9670;&nbsp;</a></span>scheduled_task_cancel()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::scheduled_task_cancel </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">Scheduled_task_handle</a>&#160;</td>
          <td class="paramname"><em>task</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Attempts to prevent the execution of a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task. </p>
<p >For semantics, in the context of the entire facility, see <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> doc header.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>See <a class="el" href="namespaceflow_1_1util.html#abe8d04de7ba9ac770112ee585b77cd20" title="Attempts to reschedule a previously scheduled (by schedule_task_from_now() or similar) task to fire i...">scheduled_task_short_fire()</a>. </td></tr>
    <tr><td class="paramname">task</td><td>See <a class="el" href="namespaceflow_1_1util.html#abe8d04de7ba9ac770112ee585b77cd20" title="Attempts to reschedule a previously scheduled (by schedule_task_from_now() or similar) task to fire i...">scheduled_task_short_fire()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if the task has not executed and will NEVER have executed, AND no other <a class="el" href="namespaceflow_1_1util.html#ad92e68a1b22556f2625292098c0036a2" title="Attempts to prevent the execution of a previously scheduled (by schedule_task_from_now() or similar) ...">scheduled_task_cancel()</a> with the same arg has succeeded before this. <code>false</code> if it has or will soon have executed because the present call occurred too late to stop it. Namely, it may have fired or short-fired already. </dd></dl>

</div>
</div>
<a id="ad339cf2543e0ad692203817b19e4e8ed" name="ad339cf2543e0ad692203817b19e4e8ed"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad339cf2543e0ad692203817b19e4e8ed">&#9670;&nbsp;</a></span>scheduled_task_canceled()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::scheduled_task_canceled </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#add471ec4a0f0b76793c9c84adb4916d5">Scheduled_task_const_handle</a>&#160;</td>
          <td class="paramname"><em>task</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns whether a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task has been canceled. </p>
<p >Note that this cannot be <code>true</code> while <a class="el" href="namespaceflow_1_1util.html#a79a0f182b38898771d669475d3e963a4" title="Returns whether a previously scheduled (by schedule_task_from_now() or similar) task has already fire...">scheduled_task_fired()</a> is <code>false</code> and vice versa (but see thread safety note below).</p>
<p >Thread safety notes in the <a class="el" href="namespaceflow_1_1util.html#a79a0f182b38898771d669475d3e963a4" title="Returns whether a previously scheduled (by schedule_task_from_now() or similar) task has already fire...">scheduled_task_fired()</a> doc header apply equally here.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>See <a class="el" href="namespaceflow_1_1util.html#a79a0f182b38898771d669475d3e963a4" title="Returns whether a previously scheduled (by schedule_task_from_now() or similar) task has already fire...">scheduled_task_fired()</a>. </td></tr>
    <tr><td class="paramname">task</td><td>See <a class="el" href="namespaceflow_1_1util.html#a79a0f182b38898771d669475d3e963a4" title="Returns whether a previously scheduled (by schedule_task_from_now() or similar) task has already fire...">scheduled_task_fired()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="a79a0f182b38898771d669475d3e963a4" name="a79a0f182b38898771d669475d3e963a4"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a79a0f182b38898771d669475d3e963a4">&#9670;&nbsp;</a></span>scheduled_task_fired()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::scheduled_task_fired </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#add471ec4a0f0b76793c9c84adb4916d5">Scheduled_task_const_handle</a>&#160;</td>
          <td class="paramname"><em>task</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns whether a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task has already fired. </p>
<p >Note that this cannot be <code>true</code> while <a class="el" href="namespaceflow_1_1util.html#ad339cf2543e0ad692203817b19e4e8ed" title="Returns whether a previously scheduled (by schedule_task_from_now() or similar) task has been cancele...">scheduled_task_canceled()</a> is <code>false</code> and vice versa (but see thread safety note below).</p>
<p >Also note that, while thread-safe, if <code>!single_threaded</code> in the original scheduling call, then the value returned might be different even if checked immediately after this function exits, in the same thread. However, if <code>single_threaded</code> (and one indeed properly uses <code>task</code> from one thread only) then it is guaranteed this value is consistent/correct synchronously in the caller's thread, until code in that thread actively changes it (e.g., by canceling task).</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>See <a class="el" href="namespaceflow_1_1util.html#a9a0812b36dc401a3b2ac5e60e2a070d0" title="Returns how long remains until a previously scheduled (by schedule_task_from_now() or similar) task f...">scheduled_task_fires_from_now_or_canceled()</a>. </td></tr>
    <tr><td class="paramname">task</td><td>See <a class="el" href="namespaceflow_1_1util.html#a9a0812b36dc401a3b2ac5e60e2a070d0" title="Returns how long remains until a previously scheduled (by schedule_task_from_now() or similar) task f...">scheduled_task_fires_from_now_or_canceled()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="a9a0812b36dc401a3b2ac5e60e2a070d0" name="a9a0812b36dc401a3b2ac5e60e2a070d0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9a0812b36dc401a3b2ac5e60e2a070d0">&#9670;&nbsp;</a></span>scheduled_task_fires_from_now_or_canceled()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79">Fine_duration</a> flow::util::scheduled_task_fires_from_now_or_canceled </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#add471ec4a0f0b76793c9c84adb4916d5">Scheduled_task_const_handle</a>&#160;</td>
          <td class="paramname"><em>task</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns how long remains until a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task fires; or negative time if that point is in the past; or special value if the task has been canceled. </p>
<p >This is based solely on what was specified when scheduling it; it may be different from when it will actually fire or has fired. However, a special value (see below) is returned, if the task has been canceled (<a class="el" href="namespaceflow_1_1util.html#ad92e68a1b22556f2625292098c0036a2" title="Attempts to prevent the execution of a previously scheduled (by schedule_task_from_now() or similar) ...">scheduled_task_cancel()</a>).</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logging, if any, will be done synchronously via this logger. </td></tr>
    <tr><td class="paramname">task</td><td>(Copy of) the handle returned by a previous <code>schedule_task_*()</code> call. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Positive duration if it is set to fire in the future; negative or zero duration otherwise; or special value <code>Fine_duration::max()</code> to indicate the task has been canceled. Note a non-<code>max()</code> (probably negative) duration will be returned even if it has already fired. </dd></dl>

</div>
</div>
<a id="abe8d04de7ba9ac770112ee585b77cd20" name="abe8d04de7ba9ac770112ee585b77cd20"></a>
<h2 class="memtitle"><span class="permalink"><a href="#abe8d04de7ba9ac770112ee585b77cd20">&#9670;&nbsp;</a></span>scheduled_task_short_fire()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::scheduled_task_short_fire </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">Scheduled_task_handle</a>&#160;</td>
          <td class="paramname"><em>task</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Attempts to reschedule a previously scheduled (by <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> or similar) task to fire immediately. </p>
<p >For semantics, in the context of the entire facility, see <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> doc header.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>See <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a>. </td></tr>
    <tr><td class="paramname">task</td><td>(Copy of) the handle returned by a previous <code>schedule_task_*()</code> call. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if the task will indeed have executed soon with <code>short_fire == true</code>. <code>false</code> if it has or will soon have executed with <code>short_file == false</code>; or if it has already been successfully canceled via <a class="el" href="namespaceflow_1_1util.html#ad92e68a1b22556f2625292098c0036a2" title="Attempts to prevent the execution of a previously scheduled (by schedule_task_from_now() or similar) ...">scheduled_task_cancel()</a>. </dd></dl>

</div>
</div>
<a id="a002c9a2f7629dfe3fdfa5632eda30dbd" name="a002c9a2f7629dfe3fdfa5632eda30dbd"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a002c9a2f7629dfe3fdfa5632eda30dbd">&#9670;&nbsp;</a></span>sequence_to_inverted_lookup_map() <span class="overload">[1/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Map , typename Sequence &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void flow::util::sequence_to_inverted_lookup_map </td>
          <td>(</td>
          <td class="paramtype">Sequence const &amp;&#160;</td>
          <td class="paramname"><em>src_seq</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Map *&#160;</td>
          <td class="paramname"><em>target_map</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Given a generic sequence (integer -&gt; object) generates a generic map (object -&gt; integer) providing inverse lookup. </p>
<p >See the 3-arg overload if you want to provide a more complex lookup function to store something else based on each index.</p>
<p >A naive way of implementing lookups otherwise would be a linear search for the object; using this will use RAM to avoid the slow searches.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Sequence</td><td>Sequence such as <code>std::vector&lt;T&gt;</code> or <code>std::array&lt;T&gt;</code>. Informally, <code>T</code> should be something light-weight and hence usable as a key type for a map type (<code>Map</code>). </td></tr>
    <tr><td class="paramname">Map</td><td>Map that maps <code>T</code> from <code>Sequence</code> to <code>size_t</code>. Example: <code>std::map&lt;T, size_t&gt;</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src_seq</td><td>Input sequence. </td></tr>
    <tr><td class="paramname">target_map</td><td>Output map. Note it will <em>not</em> be pre-cleared; informally, this means one can shove 2+ lookup maps into one. If null behavior undefined (assertion may trip). </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a0a873d1abeac7a29822e940adf4f06c9" name="a0a873d1abeac7a29822e940adf4f06c9"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0a873d1abeac7a29822e940adf4f06c9">&#9670;&nbsp;</a></span>sequence_to_inverted_lookup_map() <span class="overload">[2/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Map , typename Sequence &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void flow::util::sequence_to_inverted_lookup_map </td>
          <td>(</td>
          <td class="paramtype">Sequence const &amp;&#160;</td>
          <td class="paramname"><em>src_seq</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Map *&#160;</td>
          <td class="paramname"><em>target_map</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const Function&lt; typename Map::mapped_type(size_t)&gt; &amp;&#160;</td>
          <td class="paramname"><em>idx_to_map_val_func</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Similar to the 2-arg overload of <a class="el" href="namespaceflow_1_1util.html#a0a873d1abeac7a29822e940adf4f06c9" title="Similar to the 2-arg overload of sequence_to_inverted_lookup_map() but with the ability to store a va...">sequence_to_inverted_lookup_map()</a> but with the ability to store a value based on the index into the input sequence instead of that index itself. </p>
<p >See the 2-arg overload.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Sequence</td><td>Sequence such as <code>std::vector&lt;T&gt;</code> or <code>std::array&lt;T&gt;</code>. Informally, <code>T</code> should be something light-weight and hence usable as a key type for a map type (<code>Map</code>). </td></tr>
    <tr><td class="paramname">Map</td><td>Map that maps <code>T</code> from <code>Sequence</code> to another type <code>X</code>. Example: <code>unordered_map&lt;T, X&gt;</code>, where an <code>X</code> can be computed from a <code>size_t</code> index. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src_seq</td><td>See 2-arg overload. </td></tr>
    <tr><td class="paramname">target_map</td><td>See 2-arg overload. </td></tr>
    <tr><td class="paramname">idx_to_map_val_func</td><td>Given an index <code>idx</code> into <code>src_seq</code>, <code>(*target_map)[]</code> shall contain <code>idx_to_map_val_func(idx)</code>. Use this arg to instead perform a second lookup before storing a value in <code>*target_map</code>. Use the 2-arg overload if you'd like to store the index itself. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a09a032f8e1e77a3afc0b7df115a773e1" name="a09a032f8e1e77a3afc0b7df115a773e1"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a09a032f8e1e77a3afc0b7df115a773e1">&#9670;&nbsp;</a></span>setup_auto_cleanup()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Cleanup_func &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1util.html#ab22fd89e165a9e6deaa174bc0dfdc8de">Auto_cleanup</a> flow::util::setup_auto_cleanup </td>
          <td>(</td>
          <td class="paramtype">const Cleanup_func &amp;&#160;</td>
          <td class="paramname"><em>func</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Provides a way to execute arbitrary (cleanup) code at the exit of the current block. </p>
<p >Simply save the returned object into a local variable that will go out of scope when your code block exits. Example:</p>
<div class="fragment"><div class="line">{</div>
<div class="line">  X* x = create_x();</div>
<div class="line">  <span class="keyword">auto</span> cleanup = <a class="code hl_function" href="namespaceflow_1_1util.html#a09a032f8e1e77a3afc0b7df115a773e1">util::setup_auto_cleanup</a>([&amp;]() { delete_x(x); });</div>
<div class="line">  <span class="comment">// Now delete_x(x) will be called no matter how the current { block } exits.</span></div>
<div class="line">  <span class="comment">// ...</span></div>
<div class="line">}</div>
<div class="ttc" id="anamespaceflow_1_1util_html_a09a032f8e1e77a3afc0b7df115a773e1"><div class="ttname"><a href="namespaceflow_1_1util.html#a09a032f8e1e77a3afc0b7df115a773e1">flow::util::setup_auto_cleanup</a></div><div class="ttdeci">Auto_cleanup setup_auto_cleanup(const Cleanup_func &amp;func)</div><div class="ttdoc">Provides a way to execute arbitrary (cleanup) code at the exit of the current block.</div><div class="ttdef"><b>Definition:</b> util.hpp:307</div></div>
</div><!-- fragment --><dl class="todo"><dt><b><a class="el" href="todo.html#_todo000084">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1util.html#a09a032f8e1e77a3afc0b7df115a773e1" title="Provides a way to execute arbitrary (cleanup) code at the exit of the current block.">setup_auto_cleanup()</a> should take a function via move semantics.</dd></dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Cleanup_func</td><td>Any type such that given an instance <code>Cleanup_func f</code>, the expression <code>f()</code> is valid. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">func</td><td><code>func()</code> will be called when cleanup is needed. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>A light-weight object that, when it goes out of scope, will cause <code>func()</code> to be called. </dd></dl>

</div>
</div>
<a id="a67eecb5096dabfaff3d02c419b304540" name="a67eecb5096dabfaff3d02c419b304540"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a67eecb5096dabfaff3d02c419b304540">&#9670;&nbsp;</a></span>size_unit_convert()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename From , typename To &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">size_t flow::util::size_unit_convert </td>
          <td>(</td>
          <td class="paramtype">From&#160;</td>
          <td class="paramname"><em>num_froms</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Answers the question <em>what's the smallest integer number of <code>To</code>s sufficient to verbatim store the given number of <code>From</code>s?</em>, where <code>From</code> and <code>To</code> are POD types. </p>
<p >For example, one needs 1 <code>uint64_t</code> to store 1, 2, 3, or 4 <code>uint16_t</code>s, hence <code>size_unit_convert&lt;uint16_t, uint64_t&gt;(1 or 2 or 3 or 4) == 1</code>. Similarly, 5 or 6 or 7 or 8 -&gt; 2. It works in the opposite direction, too; if we are storing <code>uint64_t</code>s in multiples of <code>uint16_t</code>, then 1 -&gt; 4, 2 -&gt; 8, 3 -&gt; 12, etc.</p>
<p >To be clear, when <code>From</code> bit width is smaller than <code>To</code> bit width, some of the bits will be padding and presumably unused. For example, raw data buffers of arbitrary bytes are often arranged in multi-byte "words."</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">From</td><td>The POD type of the values that must be encoded in <code>From</code>s. </td></tr>
    <tr><td class="paramname">To</td><td>The POD type of the array that would store the <code>From</code>s. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">num_froms</td><td>How many <code>From</code>s does one want to encode in an array of <code>To</code>s? </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>How many <code>To</code>s are sufficient to encode <code>num_from</code> <code>From</code>s verbatim? </dd></dl>

</div>
</div>
<a id="a34ed70fa4de81a4fdb9234bfb5a3a914" name="a34ed70fa4de81a4fdb9234bfb5a3a914"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a34ed70fa4de81a4fdb9234bfb5a3a914">&#9670;&nbsp;</a></span>subtract_with_floor()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Minuend , typename Subtrahend &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">bool flow::util::subtract_with_floor </td>
          <td>(</td>
          <td class="paramtype">Minuend *&#160;</td>
          <td class="paramname"><em>minuend</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const Subtrahend &amp;&#160;</td>
          <td class="paramname"><em>subtrahend</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const Minuend &amp;&#160;</td>
          <td class="paramname"><em>floor</em> = <code>0</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Performs <code>*minuend -= subtrahend</code>, subject to a floor of <code>floor</code>. </p>
<p >Avoids underflow/overflow to the extent it's reasonably possible, but no more. The return value indicates whether the floor was hit; this allows one to chain high-performance subtractions like this:</p>
<div class="fragment"><div class="line"><span class="keywordtype">double</span> t = 44;</div>
<div class="line"><span class="keywordtype">int</span> x = rnd(); <span class="comment">// Suppose x == 123, for example.</span></div>
<div class="line"><span class="comment">// Avoids the 2nd, 3rd computation altogether, as the first detects that x &gt;= 44, and thus t == 0 regardless.</span></div>
<div class="line"><a class="code hl_function" href="namespaceflow_1_1util.html#a34ed70fa4de81a4fdb9234bfb5a3a914">subtract_with_floor</a>(&amp;t, x) &amp;&amp;</div>
<div class="line">  <a class="code hl_function" href="namespaceflow_1_1util.html#a34ed70fa4de81a4fdb9234bfb5a3a914">subtract_with_floor</a>(&amp;t, long_computation()) &amp;&amp;</div>
<div class="line">  <a class="code hl_function" href="namespaceflow_1_1util.html#a34ed70fa4de81a4fdb9234bfb5a3a914">subtract_with_floor</a>(&amp;t, another_long_computation());</div>
<div class="ttc" id="anamespaceflow_1_1util_html_a34ed70fa4de81a4fdb9234bfb5a3a914"><div class="ttname"><a href="namespaceflow_1_1util.html#a34ed70fa4de81a4fdb9234bfb5a3a914">flow::util::subtract_with_floor</a></div><div class="ttdeci">bool subtract_with_floor(Minuend *minuend, const Subtrahend &amp;subtrahend, const Minuend &amp;floor)</div><div class="ttdoc">Performs *minuend -= subtrahend, subject to a floor of floor.</div><div class="ttdef"><b>Definition:</b> util.hpp:324</div></div>
</div><!-- fragment --><dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Minuend</td><td>Numeric type. </td></tr>
    <tr><td class="paramname">Subtrahend</td><td>Numeric type, such that given <code>Subtrahend s</code>, <code>Minuend(s)</code> is something reasonable for all <code>s</code> involved. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">minuend</td><td><code>*minuend</code> is set to either <code>(*minuend - subtrahend)</code> or <code>floor</code>, whichever is higher. </td></tr>
    <tr><td class="paramname">subtrahend</td><td>Ditto. </td></tr>
    <tr><td class="paramname">floor</td><td>Ditto. Negatives are OK. Typically it's best to keep the magnitude of this small. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if <code>*minuend == floor</code> at function exit; <code>false</code> if <code>*minuend &gt; floor</code>. </dd></dl>

</div>
</div>
<a id="a71eaa4ab6a2673ed34fa8989c47a7bc0" name="a71eaa4ab6a2673ed34fa8989c47a7bc0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a71eaa4ab6a2673ed34fa8989c47a7bc0">&#9670;&nbsp;</a></span>swap() <span class="overload">[1/4]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Allocator , bool S_SHARING_ALLOWED&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void swap </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt; Allocator, S_SHARING_ALLOWED &gt; &amp;&#160;</td>
          <td class="paramname"><em>blob1</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classflow_1_1util_1_1Basic__blob.html">Basic_blob</a>&lt; Allocator, S_SHARING_ALLOWED &gt; &amp;&#160;</td>
          <td class="paramname"><em>blob2</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em> = <code>0</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Equivalent to <code>blob1.swap(blob2)</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">blob1</td><td>Object. </td></tr>
    <tr><td class="paramname">blob2</td><td>Object. </td></tr>
    <tr><td class="paramname">logger_ptr</td><td>The Logger implementation to use in <em>this</em> routine (synchronously) only. Null allowed. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="ae3835e26994f760a6324280d3a646b91" name="ae3835e26994f760a6324280d3a646b91"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae3835e26994f760a6324280d3a646b91">&#9670;&nbsp;</a></span>swap() <span class="overload">[2/4]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;bool S_SHARING_ALLOWED&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void swap </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html">Blob_with_log_context</a>&lt; S_SHARING_ALLOWED &gt; &amp;&#160;</td>
          <td class="paramname"><em>blob1</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classflow_1_1util_1_1Blob__with__log__context.html">Blob_with_log_context</a>&lt; S_SHARING_ALLOWED &gt; &amp;&#160;</td>
          <td class="paramname"><em>blob2</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>On top of the similar <a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> related function, logs using the stored log context of <code>blob1</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">blob1</td><td>See super-class related API. </td></tr>
    <tr><td class="paramname">blob2</td><td>See super-class related API. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a9bec37057b3abab90a9732d293116e5b" name="a9bec37057b3abab90a9732d293116e5b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9bec37057b3abab90a9732d293116e5b">&#9670;&nbsp;</a></span>swap() <span class="overload">[3/4]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Key , typename Mapped , typename Hash , typename Pred &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void swap </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1util_1_1Linked__hash__map.html">Linked_hash_map</a>&lt; Key, Mapped, Hash, Pred &gt; &amp;&#160;</td>
          <td class="paramname"><em>val1</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classflow_1_1util_1_1Linked__hash__map.html">Linked_hash_map</a>&lt; Key, Mapped, Hash, Pred &gt; &amp;&#160;</td>
          <td class="paramname"><em>val2</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Equivalent to <code>val1.swap(val2)</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">val1</td><td>Object. </td></tr>
    <tr><td class="paramname">val2</td><td>Object. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="ac7fd808e839d422a3f74fbea57fe367e" name="ac7fd808e839d422a3f74fbea57fe367e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac7fd808e839d422a3f74fbea57fe367e">&#9670;&nbsp;</a></span>swap() <span class="overload">[4/4]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Key , typename Hash , typename Pred &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void swap </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1util_1_1Linked__hash__set.html">Linked_hash_set</a>&lt; Key, Hash, Pred &gt; &amp;&#160;</td>
          <td class="paramname"><em>val1</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classflow_1_1util_1_1Linked__hash__set.html">Linked_hash_set</a>&lt; Key, Hash, Pred &gt; &amp;&#160;</td>
          <td class="paramname"><em>val2</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Equivalent to <code>val1.swap(val2)</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">val1</td><td>Object. </td></tr>
    <tr><td class="paramname">val2</td><td>Object. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="ad92ad411feccf73908abe6ed130d48f5" name="ad92ad411feccf73908abe6ed130d48f5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad92ad411feccf73908abe6ed130d48f5">&#9670;&nbsp;</a></span>time_since_posix_epoch()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">boost::chrono::microseconds flow::util::time_since_posix_epoch </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Get the current POSIX (Unix) time as a duration from the Epoch time point. </p>
<p >This is the amount of time &ndash; according to the user-settable system clock time &ndash; to have passed since the POSIX (Unix) Epoch &ndash; January 1st, 1970, 00:00:00 UTC &ndash; not counting leap seconds to have been inserted or deleted between then and now.</p>
<p >The <code>boost::chrono</code> duration type is chosen so as to support the entire supported resolution of the OS-exposed system clock (but probably no more than that).</p>
<h3>Known use cases, alternatives</h3>
<ul>
<li>Logging of time stamps. Output the raw value; or use boost.locale to output <code>ceil&lt;seconds&gt;()</code> in the desired human-friendly form, splicing in the left-over microseconds where desired (boost.locale lacks formatters for sub-second-resolution time points). However see below for a typically-superior alternative.</li>
<li>By subtracting return values of this at various points in time from each other, as a crude timing mechanism. (Various considerations make it just that &ndash; crude &ndash; and best replaced by <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00" title="Clock used for delicate time measurements, such that the now() method gets the current time relative ...">flow::Fine_clock</a> and the like. Moreover see <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">flow::perf::Checkpointing_timer</a>.)</li>
<li>It's a decent quick-and-dirty random seed.</li>
</ul>
<h3>Update/subtleties re. time stamp output</h3>
<p >Using this for time stamp output is no longer needed or convenient, as a much nicer way presents itself when combined with boost.chrono I/O-v2 <code>time_point</code>-outputting <code>ostream&lt;&lt;</code> overload. Just grab <code>time_point</code> <code>boost::chrono::system_clock::now()</code> (or another <code>system_clock</code>-originated value); its default-formatted <code>ostream&lt;&lt;</code> output will include date, time with microsecond+ precision, and time-zone specifier (one can choose UTC or local time).</p>
<p >However, as of this writing, it is not possible to directly obtain <em>just</em> the microsecond+ part of this, in isolation, according boost.chrono docs. (One could hack it by taking a substring.) Quote: "Unfortunately there are no formatting/parsing sequences which indicate fractional seconds." From: <a href="https://www.boost.org/doc/libs/1_76_0/doc/html/chrono/users_guide.html#chrono.users_guide.tutorial.i_o.system_clock_time_point_io">https://www.boost.org/doc/libs/1_76_0/doc/html/chrono/users_guide.html#chrono.users_guide.tutorial.i_o.system_clock_time_point_io</a>)</p>
<dl class="section return"><dt>Returns</dt><dd>A duration representing how much time has passed since the Epoch reference point (could be negative if before it). </dd></dl>

</div>
</div>
<a id="a0f681afaf67a0f917cf43a7ae893a015" name="a0f681afaf67a0f917cf43a7ae893a015"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0f681afaf67a0f917cf43a7ae893a015">&#9670;&nbsp;</a></span>to_mbit_per_sec()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Time_unit , typename N_items &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">double flow::util::to_mbit_per_sec </td>
          <td>(</td>
          <td class="paramtype">N_items&#160;</td>
          <td class="paramname"><em>items_per_time</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>bits_per_item</em> = <code>8</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Utility that converts a bandwidth in arbitrary units in both numerator and denominator to the same bandwidth in megabits per second. </p>
<p >The input bandwidth is given in "items" per <code>Time_unit(1)</code>; where <code>Time_unit</code> is an arbitrary boost.chrono <code>duration</code> type that must be explicitly provided as input; and an "item" is defined as <code>bits_per_item</code> bits. Useful at least for logging. It's probably easiest to understand by example; see below; rather than by parsing that description I just wrote.</p>
<p >To be clear (as C++ syntax is not super-expressive in this case) &ndash; the template parameter <code>Time_unit</code> is an explicit input to the function template, essentially instructing it as to in what units <code>items_per_time</code> is. Thus all uses of this function should look similar to:</p>
<div class="fragment"><div class="line"><span class="comment">// These are all equal doubles, because the (value, unit represented by value) pair is logically same in each case.</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// We&#39;ll repeatedly convert from 2400 mebibytes (1024 * 1024 bytes) per second, represented one way or another.</span></div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">size_t</span> MB_PER_SEC = 2400;</div>
<div class="line"> </div>
<div class="line"><span class="comment">// First give it as _mebibytes_ (2nd arg) per _second_ (template arg).</span></div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> mbps_from_mb_per_sec</div>
<div class="line">  = flow::util::to_mbit_per_sec&lt;chrono::seconds&gt;(MB_PER_SEC, 1024 * 8);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Now give it as _bytes_ (2nd arg omitted in favor of very common default = 8) per _second_ (template arg).</span></div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> mbps_from_b_per_sec</div>
<div class="line">  = flow::util::to_mbit_per_sec&lt;chrono::seconds&gt;(MB_PER_SEC * 1024 * 1024);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Now in _bytes_ per _hour_.</span></div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> mbps_from_b_per_hour</div>
<div class="line">  = flow::util::to_mbit_per_sec&lt;chrono::hours&gt;(MB_PER_SEC * 1024 * 1024 * 60 * 60);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Finally give it in _bytes_ per _1/30th-of-a-second_ (i.e., per frame, when the frame rate is 30fps).</span></div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> mbps_from_b_per_30fps_frame</div>
<div class="line">  = flow::util::to_mbit_per_sec&lt;chrono::duration&lt;int, ratio&lt;1, 30&gt;&gt;(MB_PER_SEC * 1024 * 1024 / 30);</div>
</div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>Megabit (1000 x 1000 = 10^6 bits) =/= mebibit (1024 x 1024 = 2^20 bits); but the latter is only about 5% more. </dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000083">Todo:</a></b></dt><dd>boost.unit "feels" like it would do this for us in some amazingly pithy and just-as-fast way. Because Boost. </dd></dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Time_unit</td><td><code>boost::chrono::duration&lt;Rep, Period&gt;</code> for some specific <code>Rep</code> and <code>Period</code>. See <code>boost::chrono::duration</code> documentation. Example types: <code>boost::chrono::milliseconds</code>; <code>boost::chrono::seconds</code>; see example use code above. </td></tr>
    <tr><td class="paramname">N_items</td><td>Some (not necessarily integral) numeric type. Strictly speaking, any type convertible to <code>double</code> works. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">items_per_time</td><td>The value, in items per <code>Time_unit(1)</code> (where there are <code>bits_per_item</code> bits in 1 item) to convert to megabits per second. Note this need not be an integer. </td></tr>
    <tr><td class="paramname">bits_per_item</td><td>Number of bits in an item, where <code>items_per_time</code> is given as a number of items. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:32 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
